Merge branch 'master' into staging-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jan 2014 13:44:53 +0000 (05:44 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jan 2014 13:44:53 +0000 (05:44 -0800)
We need the network changes in staging-next in order to be able to fix
up the rtl8821ae driver to build properly.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
75 files changed:
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/rtl8821ae/Kconfig [new file with mode: 0644]
drivers/staging/rtl8821ae/Makefile [new file with mode: 0644]
drivers/staging/rtl8821ae/TODO [new file with mode: 0644]
drivers/staging/rtl8821ae/base.c [new file with mode: 0644]
drivers/staging/rtl8821ae/base.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbt_precomp.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8723b1ant.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8723b1ant.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8723b2ant.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtc8723b2ant.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/rtl_btc.c [new file with mode: 0644]
drivers/staging/rtl8821ae/btcoexist/rtl_btc.h [new file with mode: 0644]
drivers/staging/rtl8821ae/cam.c [new file with mode: 0644]
drivers/staging/rtl8821ae/cam.h [new file with mode: 0644]
drivers/staging/rtl8821ae/compat.h [new file with mode: 0644]
drivers/staging/rtl8821ae/core.c [new file with mode: 0644]
drivers/staging/rtl8821ae/core.h [new file with mode: 0644]
drivers/staging/rtl8821ae/debug.c [new file with mode: 0644]
drivers/staging/rtl8821ae/debug.h [new file with mode: 0644]
drivers/staging/rtl8821ae/efuse.c [new file with mode: 0644]
drivers/staging/rtl8821ae/efuse.h [new file with mode: 0644]
drivers/staging/rtl8821ae/pci.c [new file with mode: 0644]
drivers/staging/rtl8821ae/pci.h [new file with mode: 0644]
drivers/staging/rtl8821ae/ps.c [new file with mode: 0644]
drivers/staging/rtl8821ae/ps.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rc.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rc.h [new file with mode: 0644]
drivers/staging/rtl8821ae/regd.c [new file with mode: 0644]
drivers/staging/rtl8821ae/regd.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/btc.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/def.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/dm.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/dm.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/fw.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/fw.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/hal_bt_coexist.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/hal_bt_coexist.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/hal_btc.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/hw.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/hw.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/led.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/led.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/phy.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/phy.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/pwrseq.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/pwrseq.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/pwrseqcmd.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/pwrseqcmd.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/reg.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/rf.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/rf.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/sw.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/sw.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/table.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/table.h [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/trx.c [new file with mode: 0644]
drivers/staging/rtl8821ae/rtl8821ae/trx.h [new file with mode: 0644]
drivers/staging/rtl8821ae/stats.c [new file with mode: 0644]
drivers/staging/rtl8821ae/stats.h [new file with mode: 0644]
drivers/staging/rtl8821ae/wifi.h [new file with mode: 0644]

index 4bb6b11..810bcb3 100644 (file)
@@ -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"
index 9f07e5e..d925cde 100644 (file)
@@ -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 (file)
index 0000000..a432e1a
--- /dev/null
@@ -0,0 +1,12 @@
+config R8821AE
+       tristate "RealTek RTL8821AE Wireless LAN NIC driver"
+       depends on PCI && WLAN
+       depends on m
+       depends on BROKEN
+       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 (file)
index 0000000..8a23bd7
--- /dev/null
@@ -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 (file)
index 0000000..3ee7529
--- /dev/null
@@ -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 (file)
index 0000000..b5a50d0
--- /dev/null
@@ -0,0 +1,1874 @@
+/******************************************************************************
+ *
+ * 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->channel_change_time = 100;
+       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 (compare_ether_addr(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 (compare_ether_addr(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 (file)
index 0000000..629d14f
--- /dev/null
@@ -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 (file)
index 0000000..b30f17a
--- /dev/null
@@ -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 ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi 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 ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration
+                       {
+                               if (wait_count <= 2)
+                                       m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+                               else
+                                       m = 1;
+
+                               if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã 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, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration
+               {
+                       if (wait_count == 1)
+                               m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+                       else
+                               m = 1;
+
+                       if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã 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)
+               {\r
+                       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 (file)
index 0000000..37bdab5
--- /dev/null
@@ -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 (file)
index 0000000..e619923
--- /dev/null
@@ -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 ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi 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 ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration
+                       {
+                               if (WaitCount <= 2)
+                                       m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+                               else
+                                       m = 1;
+
+                               if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã 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, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration
+               {
+                       if (WaitCount == 1)
+                               m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+                       else
+                               m = 1;
+
+                       if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã 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 (file)
index 0000000..60992f5
--- /dev/null
@@ -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 (file)
index 0000000..d538ba3
--- /dev/null
@@ -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 (file)
index 0000000..973d0ea
--- /dev/null
@@ -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 ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi 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 ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration
+                       {
+                               if (WaitCount <= 2)
+                                       m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+                               else
+                                       m = 1;
+
+                               if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã 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, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration
+               {
+                       if (WaitCount == 1)
+                               m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+                       else
+                               m = 1;
+
+                       if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã 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 (file)
index 0000000..a759b75
--- /dev/null
@@ -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 (file)
index 0000000..44ec785
--- /dev/null
@@ -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 (file)
index 0000000..6d109ed
--- /dev/null
@@ -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 (file)
index 0000000..180d6f1
--- /dev/null
@@ -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, ("[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 ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi 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 ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration
+                       {
+                               if (WaitCount <= 2)
+                                       m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+                               else
+                                       m = 1;
+
+                               if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã 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, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration
+               {
+                       if (WaitCount == 1)
+                               m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+                       else
+                               m = 1;
+
+                       if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã 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"));
+               }
+
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], max Interval = %d\n", maxInterval));
+               if(maxInterval == 1)
+               {
+                       if(bTxPause)
+                       {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], TxPause = 1\n"));
+
+                               if(pCoexDm->curPsTdma == 1)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 5);
+                                       pCoexDm->psTdmaDuAdjType = 5;
+                               }
+                               else if(pCoexDm->curPsTdma == 2)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                                       pCoexDm->psTdmaDuAdjType = 6;
+                               }
+                               else if(pCoexDm->curPsTdma == 3)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                       pCoexDm->psTdmaDuAdjType = 7;
+                               }
+                               else if(pCoexDm->curPsTdma == 4)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+                                       pCoexDm->psTdmaDuAdjType = 8;
+                               }
+                               if(pCoexDm->curPsTdma == 9)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 13);
+                                       pCoexDm->psTdmaDuAdjType = 13;
+                               }
+                               else if(pCoexDm->curPsTdma == 10)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                                       pCoexDm->psTdmaDuAdjType = 14;
+                               }
+                               else if(pCoexDm->curPsTdma == 11)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                       pCoexDm->psTdmaDuAdjType = 15;
+                               }
+                               else if(pCoexDm->curPsTdma == 12)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 16);
+                                       pCoexDm->psTdmaDuAdjType = 16;
+                               }
+                               
+                               if(result == -1)
+                               {                                       
+                                       if(pCoexDm->curPsTdma == 5)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                                               pCoexDm->psTdmaDuAdjType = 6;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 6)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 7)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+                                               pCoexDm->psTdmaDuAdjType = 8;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 13)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                                               pCoexDm->psTdmaDuAdjType = 14;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 14)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 15)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 16);
+                                               pCoexDm->psTdmaDuAdjType = 16;
+                                       }
+                               } 
+                               else if (result == 1)
+                               {
+                                       if(pCoexDm->curPsTdma == 8)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 7)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                                               pCoexDm->psTdmaDuAdjType = 6;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 6)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 5);
+                                               pCoexDm->psTdmaDuAdjType = 5;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 16)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 15)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                                               pCoexDm->psTdmaDuAdjType = 14;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 14)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 13);
+                                               pCoexDm->psTdmaDuAdjType = 13;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], TxPause = 0\n"));
+                               if(pCoexDm->curPsTdma == 5)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
+                                       pCoexDm->psTdmaDuAdjType = 1;
+                               }
+                               else if(pCoexDm->curPsTdma == 6)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                                       pCoexDm->psTdmaDuAdjType = 2;
+                               }
+                               else if(pCoexDm->curPsTdma == 7)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                       pCoexDm->psTdmaDuAdjType = 3;
+                               }
+                               else if(pCoexDm->curPsTdma == 8)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+                                       pCoexDm->psTdmaDuAdjType = 4;
+                               }
+                               if(pCoexDm->curPsTdma == 13)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+                                       pCoexDm->psTdmaDuAdjType = 9;
+                               }
+                               else if(pCoexDm->curPsTdma == 14)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                                       pCoexDm->psTdmaDuAdjType = 10;
+                               }
+                               else if(pCoexDm->curPsTdma == 15)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                       pCoexDm->psTdmaDuAdjType = 11;
+                               }
+                               else if(pCoexDm->curPsTdma == 16)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+                                       pCoexDm->psTdmaDuAdjType = 12;
+                               }
+                               
+                               if(result == -1)
+                               {
+                                       if(pCoexDm->curPsTdma == 1)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                                               pCoexDm->psTdmaDuAdjType = 2;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 2)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 3)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+                                               pCoexDm->psTdmaDuAdjType = 4;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 9)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                                               pCoexDm->psTdmaDuAdjType = 10;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 10)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 11;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 11)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+                                               pCoexDm->psTdmaDuAdjType = 12;
+                                       }
+                               } 
+                               else if (result == 1)
+                               {
+                                       if(pCoexDm->curPsTdma == 4)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 3)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                                               pCoexDm->psTdmaDuAdjType = 2;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 2)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
+                                               pCoexDm->psTdmaDuAdjType = 1;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 12)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 11;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 11)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                                               pCoexDm->psTdmaDuAdjType = 10;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 10)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+                                               pCoexDm->psTdmaDuAdjType = 9;
+                                       }
+                               }
+                       }
+               }
+               else if(maxInterval == 2)
+               {
+                       if(bTxPause)
+                       {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], TxPause = 1\n"));
+                               if(pCoexDm->curPsTdma == 1)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                                       pCoexDm->psTdmaDuAdjType = 6;
+                               }
+                               else if(pCoexDm->curPsTdma == 2)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                                       pCoexDm->psTdmaDuAdjType = 6;
+                               }
+                               else if(pCoexDm->curPsTdma == 3)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                       pCoexDm->psTdmaDuAdjType = 7;
+                               }
+                               else if(pCoexDm->curPsTdma == 4)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+                                       pCoexDm->psTdmaDuAdjType = 8;
+                               }
+                               if(pCoexDm->curPsTdma == 9)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                                       pCoexDm->psTdmaDuAdjType = 14;
+                               }
+                               else if(pCoexDm->curPsTdma == 10)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                                       pCoexDm->psTdmaDuAdjType = 14;
+                               }
+                               else if(pCoexDm->curPsTdma == 11)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                       pCoexDm->psTdmaDuAdjType = 15;
+                               }
+                               else if(pCoexDm->curPsTdma == 12)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 16);
+                                       pCoexDm->psTdmaDuAdjType = 16;
+                               }
+                               if(result == -1)
+                               {
+                                       if(pCoexDm->curPsTdma == 5) 
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                                               pCoexDm->psTdmaDuAdjType = 6;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 6)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 7)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+                                               pCoexDm->psTdmaDuAdjType = 8;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 13)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                                               pCoexDm->psTdmaDuAdjType = 14;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 14)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 15)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 16);
+                                               pCoexDm->psTdmaDuAdjType = 16;
+                                       }
+                               } 
+                               else if (result == 1)
+                               {
+                                       if(pCoexDm->curPsTdma == 8)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 7)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                                               pCoexDm->psTdmaDuAdjType = 6;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 6)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                                               pCoexDm->psTdmaDuAdjType = 6;
+                                       }                                       
+                                       else if(pCoexDm->curPsTdma == 16)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 15)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                                               pCoexDm->psTdmaDuAdjType = 14;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 14)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                                               pCoexDm->psTdmaDuAdjType = 14;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], TxPause = 0\n"));
+                               if(pCoexDm->curPsTdma == 5)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                                       pCoexDm->psTdmaDuAdjType = 2;
+                               }
+                               else if(pCoexDm->curPsTdma == 6)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                                       pCoexDm->psTdmaDuAdjType = 2;
+                               }
+                               else if(pCoexDm->curPsTdma == 7)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                       pCoexDm->psTdmaDuAdjType = 3;
+                               }
+                               else if(pCoexDm->curPsTdma == 8)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+                                       pCoexDm->psTdmaDuAdjType = 4;
+                               }
+                               if(pCoexDm->curPsTdma == 13)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                                       pCoexDm->psTdmaDuAdjType = 10;
+                               }
+                               else if(pCoexDm->curPsTdma == 14)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                                       pCoexDm->psTdmaDuAdjType = 10;
+                               }
+                               else if(pCoexDm->curPsTdma == 15)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                       pCoexDm->psTdmaDuAdjType = 11;
+                               }
+                               else if(pCoexDm->curPsTdma == 16)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+                                       pCoexDm->psTdmaDuAdjType = 12;
+                               }
+                               if(result == -1)
+                               {
+                                       if(pCoexDm->curPsTdma == 1)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                                               pCoexDm->psTdmaDuAdjType = 2;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 2)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 3)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+                                               pCoexDm->psTdmaDuAdjType = 4;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 9)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                                               pCoexDm->psTdmaDuAdjType = 10;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 10)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 11;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 11)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+                                               pCoexDm->psTdmaDuAdjType = 12;
+                                       }
+                               } 
+                               else if (result == 1)
+                               {
+                                       if(pCoexDm->curPsTdma == 4)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 3)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                                               pCoexDm->psTdmaDuAdjType = 2;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 2)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                                               pCoexDm->psTdmaDuAdjType = 2;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 12)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 11;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 11)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                                               pCoexDm->psTdmaDuAdjType = 10;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 10)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                                               pCoexDm->psTdmaDuAdjType = 10;
+                                       }
+                               }
+                       }
+               }
+               else if(maxInterval == 3)
+               {
+                       if(bTxPause)
+                       {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], TxPause = 1\n"));
+                               if(pCoexDm->curPsTdma == 1)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                       pCoexDm->psTdmaDuAdjType = 7;
+                               }
+                               else if(pCoexDm->curPsTdma == 2)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                       pCoexDm->psTdmaDuAdjType = 7;
+                               }
+                               else if(pCoexDm->curPsTdma == 3)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                       pCoexDm->psTdmaDuAdjType = 7;
+                               }
+                               else if(pCoexDm->curPsTdma == 4)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+                                       pCoexDm->psTdmaDuAdjType = 8;
+                               }
+                               if(pCoexDm->curPsTdma == 9)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                       pCoexDm->psTdmaDuAdjType = 15;
+                               }
+                               else if(pCoexDm->curPsTdma == 10)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                       pCoexDm->psTdmaDuAdjType = 15;
+                               }
+                               else if(pCoexDm->curPsTdma == 11)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                       pCoexDm->psTdmaDuAdjType = 15;
+                               }
+                               else if(pCoexDm->curPsTdma == 12)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 16);
+                                       pCoexDm->psTdmaDuAdjType = 16;
+                               }
+                               if(result == -1)
+                               {
+                                       if(pCoexDm->curPsTdma == 5) 
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 6)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 7)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+                                               pCoexDm->psTdmaDuAdjType = 8;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 13)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 14)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 15)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 16);
+                                               pCoexDm->psTdmaDuAdjType = 16;
+                                       }
+                               } 
+                               else if (result == 1)
+                               {
+                                       if(pCoexDm->curPsTdma == 8)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 7)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 6)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+                                               pCoexDm->psTdmaDuAdjType = 7;
+                                       }                                       
+                                       else if(pCoexDm->curPsTdma == 16)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 15)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 14)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+                                               pCoexDm->psTdmaDuAdjType = 15;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], TxPause = 0\n"));
+                               if(pCoexDm->curPsTdma == 5)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                       pCoexDm->psTdmaDuAdjType = 3;
+                               }
+                               else if(pCoexDm->curPsTdma == 6)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                       pCoexDm->psTdmaDuAdjType = 3;
+                               }
+                               else if(pCoexDm->curPsTdma == 7)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                       pCoexDm->psTdmaDuAdjType = 3;
+                               }
+                               else if(pCoexDm->curPsTdma == 8)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+                                       pCoexDm->psTdmaDuAdjType = 4;
+                               }
+                               if(pCoexDm->curPsTdma == 13)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                       pCoexDm->psTdmaDuAdjType = 11;
+                               }
+                               else if(pCoexDm->curPsTdma == 14)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                       pCoexDm->psTdmaDuAdjType = 11;
+                               }
+                               else if(pCoexDm->curPsTdma == 15)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                       pCoexDm->psTdmaDuAdjType = 11;
+                               }
+                               else if(pCoexDm->curPsTdma == 16)
+                               {
+                                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+                                       pCoexDm->psTdmaDuAdjType = 12;
+                               }
+                               if(result == -1)
+                               {
+                                       if(pCoexDm->curPsTdma == 1)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 2)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 3)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+                                               pCoexDm->psTdmaDuAdjType = 4;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 9)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 11;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 10)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 11;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 11)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+                                               pCoexDm->psTdmaDuAdjType = 12;
+                                       }
+                               } 
+                               else if (result == 1)
+                               {
+                                       if(pCoexDm->curPsTdma == 4)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 3)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 2)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+                                               pCoexDm->psTdmaDuAdjType = 3;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 12)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 11;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 11)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 11;
+                                       }
+                                       else if(pCoexDm->curPsTdma == 10)
+                                       {
+                                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+                                               pCoexDm->psTdmaDuAdjType = 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(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType)
+       {
+               BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[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)
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, pCoexDm->psTdmaDuAdjType);
+               }
+               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
+halbtc8723a2ant_ActionSco(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte  wifiRssiState, wifiRssiState1;
+       u4Byte  wifiBw;
+
+       if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist))
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+       else    
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+       
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+               }
+               else
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+               }
+
+               // sw mechanism         
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0);
+               wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0);
+               
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+               }
+               else
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+               }
+               
+               // sw mechanism
+               if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }               
+       }
+}
+
+
+VOID
+halbtc8723a2ant_ActionHid(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte  wifiRssiState, wifiRssiState1;
+       u4Byte  wifiBw;
+
+       if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist))
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+       else    
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+               }
+               else
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 13);
+               }
+
+               // sw mechanism
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0);
+               wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0);
+
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+               }
+               else
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 13);
+               }
+
+               // sw mechanism
+               if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }               
+       }
+}
+
+//A2DP only / PAN(EDR) only/ A2DP+PAN(HS)
+VOID
+halbtc8723a2ant_ActionA2dp(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte          wifiRssiState, wifiRssiState1, btInfoExt;
+       u4Byte          wifiBw;
+
+       btInfoExt = pCoexSta->btInfoExt;
+
+       if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist))
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+       else    
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+       
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       if(btInfoExt&BIT0)      //a2dp rate, 1:basic /0:edr
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3);
+                       }
+                       else
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1);
+                       }
+               }
+               else
+               {
+                       if(btInfoExt&BIT0)      //a2dp rate, 1:basic /0:edr
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, true, 3);
+                       }
+                       else
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, true, 1);
+                       }
+               }
+
+               // sw mechanism         
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0);
+               wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0);
+               
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       if(btInfoExt&BIT0)      //a2dp rate, 1:basic /0:edr
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3);
+                       }
+                       else
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1);
+                       }
+               }
+               else
+               {
+                       if(btInfoExt&BIT0)      //a2dp rate, 1:basic /0:edr
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, true, 3);
+                       }
+                       else
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, true, 1);
+                       }
+               }
+               
+               // sw mechanism
+               if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }               
+       }
+}
+
+VOID
+halbtc8723a2ant_ActionPanEdr(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte          wifiRssiState, wifiRssiState1, btInfoExt;
+       u4Byte          wifiBw;
+       
+       btInfoExt = pCoexSta->btInfoExt;
+
+       if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist))
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+       else    
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+                       
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+               }
+               else
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+               }
+
+               // sw mechanism
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0);
+               wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0);
+               
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+               }
+               else
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+               }
+
+               // sw mechanism
+               if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+       }
+}
+
+
+//PAN(HS) only
+VOID
+halbtc8723a2ant_ActionPanHs(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte          wifiRssiState;
+       u4Byte          wifiBw;
+
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+               }
+               else
+               {
+                       halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+               }
+               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+               // sw mechanism         
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+               }
+               else
+               {
+                       halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+               }
+
+               // sw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+       }
+}
+
+//PAN(EDR)+A2DP
+VOID
+halbtc8723a2ant_ActionPanEdrA2dp(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte          wifiRssiState, wifiRssiState1, btInfoExt;
+       u4Byte          wifiBw;
+
+       btInfoExt = pCoexSta->btInfoExt;
+
+       if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist))
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+       else    
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                       }
+               }
+               else
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                       }
+               }
+
+               // sw mechanism
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0);
+               wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0);
+               
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+                       }
+               }
+               else
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+                       }
+               }
+
+               // sw mechanism
+               if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+       }
+}
+
+VOID
+halbtc8723a2ant_ActionPanEdrHid(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte          wifiRssiState, wifiRssiState1;
+       u4Byte          wifiBw;
+
+       if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist))
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+       else    
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10); 
+               }
+               else
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14); 
+               }
+
+               // sw mechanism
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0);
+               wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0);
+               
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+               }
+               else
+               {
+                       halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+               }
+               
+               // sw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+       }
+}
+
+// HID+A2DP+PAN(EDR)
+VOID
+halbtc8723a2ant_ActionHidA2dpPanEdr(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte          wifiRssiState, wifiRssiState1, btInfoExt;
+       u4Byte          wifiBw;
+
+       btInfoExt = pCoexSta->btInfoExt;
+
+       if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist))
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+       else    
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+                       
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                       }
+               }
+               else
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 16);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                       }
+               }
+               
+               // sw mechanism
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0);
+               wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0);
+               
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+                       }
+               }
+               else
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 16);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+                       }
+               }
+
+               // sw mechanism
+               if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+       }
+}
+
+VOID
+halbtc8723a2ant_ActionHidA2dp(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u1Byte          wifiRssiState, wifiRssiState1, btInfoExt;
+       u4Byte          wifiBw;
+
+       btInfoExt = pCoexSta->btInfoExt;
+
+       if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist))
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+       else    
+               halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+       halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+       pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+       if(BTC_WIFI_BW_HT40 == wifiBw)
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0);
+               
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, true, FALSE, 3);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, true, FALSE, 1);
+                       }
+               }
+               else
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, true, true, 3);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, true, true, 1);
+                       }
+               }
+               
+               // sw mechanism
+               halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+               halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+               halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+       }
+       else
+       {
+               wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0);
+               wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0);
+               
+               // fw mechanism
+               if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, true, FALSE, 3);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, true, FALSE, 1);
+                       }
+               }
+               else
+               {
+                       if(btInfoExt&BIT0)      //a2dp basic rate
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, true, true, 3);
+                       }
+                       else                            //a2dp edr rate
+                       {
+                               halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, true, true, 1);
+                       }
+               }
+
+               // sw mechanism
+               if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) ||
+                       (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) )
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, true);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+               else
+               {
+                       halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+                       halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+               }
+       }
+}
+
+VOID
+halbtc8723a2ant_RunCoexistMechanism(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       PBTC_STACK_INFO         pStackInfo=&pBtCoexist->stack_info;
+       u1Byte                          btInfoOriginal=0, btRetryCnt=0;
+       u1Byte                          algorithm=0;
+
+       if(pBtCoexist->manual_control)
+       {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Manual control!!!\n"));
+               return;
+       }
+
+       if(pStackInfo->bProfileNotified)
+       {
+               if(pCoexSta->bHoldForStackOperation)
+               {
+                       // if bt inquiry/page/pair, do not execute.
+                       return;
+               }
+               
+               algorithm = halbtc8723a2ant_ActionAlgorithm(pBtCoexist);
+               if(pCoexSta->bHoldPeriodCnt && (BT_8723A_2ANT_COEX_ALGO_PANHS!=algorithm))
+               {
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex],Hold BT inquiry/page scan setting (cnt = %d)!!\n", 
+                               pCoexSta->bHoldPeriodCnt));
+                       if(pCoexSta->bHoldPeriodCnt >= 6)
+                       {
+                               pCoexSta->bHoldPeriodCnt = 0;
+                               // next time the coexist parameters should be reset again.
+                       }
+                       else
+                               pCoexSta->bHoldPeriodCnt++;
+                       return;
+               }
+
+               pCoexDm->curAlgorithm = algorithm;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Algorithm = %d \n", pCoexDm->curAlgorithm));
+               if(halbtc8723a2ant_IsCommonAction(pBtCoexist))
+               {
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant common.\n"));
+                       pCoexDm->bResetTdmaAdjust = true;
+               }
+               else
+               {
+                       if(pCoexDm->curAlgorithm != pCoexDm->preAlgorithm)
+                       {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", 
+                                       pCoexDm->preAlgorithm, pCoexDm->curAlgorithm));
+                               pCoexDm->bResetTdmaAdjust = true;
+                       }
+                       switch(pCoexDm->curAlgorithm)
+                       {
+                               case BT_8723A_2ANT_COEX_ALGO_SCO:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = SCO.\n"));
+                                       halbtc8723a2ant_ActionSco(pBtCoexist);
+                                       break;
+                               case BT_8723A_2ANT_COEX_ALGO_HID:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = HID.\n"));
+                                       halbtc8723a2ant_ActionHid(pBtCoexist);
+                                       break;
+                               case BT_8723A_2ANT_COEX_ALGO_A2DP:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = A2DP.\n"));
+                                       halbtc8723a2ant_ActionA2dp(pBtCoexist);
+                                       break;
+                               case BT_8723A_2ANT_COEX_ALGO_PANEDR:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n"));
+                                       halbtc8723a2ant_ActionPanEdr(pBtCoexist);
+                                       break;
+                               case BT_8723A_2ANT_COEX_ALGO_PANHS:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = HS mode.\n"));
+                                       halbtc8723a2ant_ActionPanHs(pBtCoexist);
+                                       break;
+                               case BT_8723A_2ANT_COEX_ALGO_PANEDR_A2DP:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n"));
+                                       halbtc8723a2ant_ActionPanEdrA2dp(pBtCoexist);
+                                       break;
+                               case BT_8723A_2ANT_COEX_ALGO_PANEDR_HID:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n"));
+                                       halbtc8723a2ant_ActionPanEdrHid(pBtCoexist);
+                                       break;
+                               case BT_8723A_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n"));
+                                       halbtc8723a2ant_ActionHidA2dpPanEdr(pBtCoexist);
+                                       break;
+                               case BT_8723A_2ANT_COEX_ALGO_HID_A2DP:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n"));
+                                       halbtc8723a2ant_ActionHidA2dp(pBtCoexist);
+                                       break;
+                               default:
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n"));
+                                       halbtc8723a2ant_CoexAllOff(pBtCoexist);
+                                       break;
+                       }
+                       pCoexDm->preAlgorithm = pCoexDm->curAlgorithm;
+               }
+       }
+}
+
+//============================================================
+// work around function start with wa_halbtc8723a2ant_
+//============================================================
+VOID
+wa_halbtc8723a2ant_MonitorC2h(
+       IN      PBTC_COEXIST                    pBtCoexist
+       )
+{
+       u1Byte  tmp1b=0x0;
+       u4Byte  curC2hTotalCnt=0x0;
+       static u4Byte   preC2hTotalCnt=0x0, sameCntPollingTime=0x0;
+
+       curC2hTotalCnt+=pCoexSta->btInfoC2hCnt[BT_INFO_SRC_8723A_2ANT_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 EXhalbtc8723a2ant_
+//============================================================
+VOID
+EXhalbtc8723a2ant_InitHwConfig(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       u4Byte  u4Tmp=0;
+       u1Byte  u1Tmp=0;
+
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], 2Ant Init HW Config!!\n"));
+
+       // backup rf 0x1e value
+       pCoexDm->btRf0x1eBackup = 
+               pBtCoexist->btc_get_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff);
+
+       // Enable counter statistics
+       pBtCoexist->btc_write_1byte(pBtCoexist, 0x76e, 0x4);
+       pBtCoexist->btc_write_1byte(pBtCoexist, 0x778, 0x3);
+       pBtCoexist->btc_write_1byte(pBtCoexist, 0x40, 0x20);
+}
+
+VOID
+EXhalbtc8723a2ant_InitCoexDm(
+       IN      PBTC_COEXIST            pBtCoexist
+       )
+{
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], Coex Mechanism Init!!\n"));
+       
+       halbtc8723a2ant_InitCoexDm(pBtCoexist);
+}
+
+VOID
+EXhalbtc8723a2ant_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_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus)? "idle":(  (BT_8723A_2ANT_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_2ANT_MAX; i++)
+       {
+               if(pCoexSta->btInfoC2hCnt[i])
+               {                               
+                       CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8723a2Ant[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);
+       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);
+
+       // 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/ %d ", "DecBtPwr/ IgnWlanAct", \
+                       pCoexDm->bCurDecBtPwr, 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
+EXhalbtc8723a2ant_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"));
+               halbtc8723a2ant_CoexAllOff(pBtCoexist);
+       }
+       else if(BTC_IPS_LEAVE == type)
+       {
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], IPS LEAVE notify\n"));
+               //halbtc8723a2ant_InitCoexDm(pBtCoexist);
+       }
+}
+
+VOID
+EXhalbtc8723a2ant_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"));
+       }
+}
+
+VOID
+EXhalbtc8723a2ant_ScanNotify(
+       IN      PBTC_COEXIST            pBtCoexist,
+       IN      u1Byte                  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
+EXhalbtc8723a2ant_ConnectNotify(
+       IN      PBTC_COEXIST            pBtCoexist,
+       IN      u1Byte                  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
+EXhalbtc8723a2ant_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"));
+       }
+
+       halbtc8723a2ant_IndicateWifiChnlBwInfo(pBtCoexist, type);
+}
+
+VOID
+EXhalbtc8723a2ant_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"));
+       }
+}
+
+VOID
+EXhalbtc8723a2ant_BtInfoNotify(
+       IN      PBTC_COEXIST            pBtCoexist,
+       IN      pu1Byte                 tmpBuf,
+       IN      u1Byte                  length
+       )
+{
+       u1Byte                  btInfo=0;
+       u1Byte                  i, rspSource=0;
+       BOOLEAN                 bBtBusy=FALSE, limited_dig=FALSE;
+       BOOLEAN                 bWifiConnected=FALSE, bBtHsOn=FALSE;
+
+       pCoexSta->bC2hBtInfoReqSent = FALSE;
+       
+       rspSource = BT_INFO_SRC_8723A_2ANT_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_2ANT_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_2ANT_B_INQ_PAGE)
+       {
+               pCoexSta->bC2hBtInquiryPage = true;
+       }
+       else
+       {
+               pCoexSta->bC2hBtInquiryPage = FALSE;
+       }
+}
+
+VOID
+EXhalbtc8723a2ant_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"));
+               pCoexSta->bHoldForStackOperation = true;
+               pCoexSta->bHoldPeriodCnt = 1;
+               halbtc8723a2ant_BtInquiryPage(pBtCoexist);
+       }
+       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"));
+               pCoexSta->bHoldForStackOperation = FALSE;
+       }
+}
+
+VOID
+EXhalbtc8723a2ant_HaltNotify(
+       IN      PBTC_COEXIST                    pBtCoexist
+       )
+{
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Halt notify\n"));
+
+       halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, true);
+       EXhalbtc8723a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT);
+}
+
+VOID
+EXhalbtc8723a2ant_Periodical(
+       IN      PBTC_COEXIST                    pBtCoexist
+       )
+{
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], 2Ant Periodical!!\n"));
+
+       // work around for c2h hang
+       wa_halbtc8723a2ant_MonitorC2h(pBtCoexist);
+       
+       halbtc8723a2ant_QueryBtInfo(pBtCoexist);
+       halbtc8723a2ant_MonitorBtCtr(pBtCoexist);
+       halbtc8723a2ant_MonitorBtEnableDisable(pBtCoexist);
+
+       halbtc8723a2ant_RunCoexistMechanism(pBtCoexist);
+}
+
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.h b/drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.h
new file mode 100644 (file)
index 0000000..c07d373
--- /dev/null
@@ -0,0 +1,179 @@
+//===========================================
+// The following is for 8723A 2Ant BT Co-exist definition
+//===========================================
+#define        BT_INFO_8723A_2ANT_B_FTP                                                BIT7
+#define        BT_INFO_8723A_2ANT_B_A2DP                                       BIT6
+#define        BT_INFO_8723A_2ANT_B_HID                                                BIT5
+#define        BT_INFO_8723A_2ANT_B_SCO_BUSY                           BIT4
+#define        BT_INFO_8723A_2ANT_B_ACL_BUSY                           BIT3
+#define        BT_INFO_8723A_2ANT_B_INQ_PAGE                           BIT2
+#define        BT_INFO_8723A_2ANT_B_SCO_ESCO                           BIT1
+#define        BT_INFO_8723A_2ANT_B_CONNECTION                         BIT0
+
+#define                BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT             2
+
+typedef enum _BT_INFO_SRC_8723A_2ANT{
+       BT_INFO_SRC_8723A_2ANT_WIFI_FW                  = 0x0,
+       BT_INFO_SRC_8723A_2ANT_BT_RSP                           = 0x1,
+       BT_INFO_SRC_8723A_2ANT_BT_ACTIVE_SEND           = 0x2,
+       BT_INFO_SRC_8723A_2ANT_MAX
+}BT_INFO_SRC_8723A_2ANT,*PBT_INFO_SRC_8723A_2ANT;
+
+typedef enum _BT_8723A_2ANT_BT_STATUS{
+       BT_8723A_2ANT_BT_STATUS_IDLE                            = 0x0,
+       BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE  = 0x1,
+       BT_8723A_2ANT_BT_STATUS_NON_IDLE                        = 0x2,
+       BT_8723A_2ANT_BT_STATUS_MAX
+}BT_8723A_2ANT_BT_STATUS,*PBT_8723A_2ANT_BT_STATUS;
+
+typedef enum _BT_8723A_2ANT_COEX_ALGO{
+       BT_8723A_2ANT_COEX_ALGO_UNDEFINED                       = 0x0,
+       BT_8723A_2ANT_COEX_ALGO_SCO                             = 0x1,
+       BT_8723A_2ANT_COEX_ALGO_HID                             = 0x2,
+       BT_8723A_2ANT_COEX_ALGO_A2DP                            = 0x3,
+       BT_8723A_2ANT_COEX_ALGO_PANEDR                  = 0x4,
+       BT_8723A_2ANT_COEX_ALGO_PANHS                   = 0x5,
+       BT_8723A_2ANT_COEX_ALGO_PANEDR_A2DP             = 0x6,
+       BT_8723A_2ANT_COEX_ALGO_PANEDR_HID              = 0x7,
+       BT_8723A_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x8,
+       BT_8723A_2ANT_COEX_ALGO_HID_A2DP                        = 0x9,
+       BT_8723A_2ANT_COEX_ALGO_MAX
+}BT_8723A_2ANT_COEX_ALGO,*PBT_8723A_2ANT_COEX_ALGO;
+
+typedef struct _COEX_DM_8723A_2ANT{
+       // fw mechanism
+       BOOLEAN         bPreDecBtPwr;
+       BOOLEAN         bCurDecBtPwr;
+       //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         bResetTdmaAdjust;
+       BOOLEAN         bPrePsTdmaOn;
+       BOOLEAN         bCurPsTdmaOn;
+       //BOOLEAN               bPreBtAutoReport;
+       //BOOLEAN               bCurBtAutoReport;
+
+       // 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          preVal0x6c8;
+       u4Byte          curVal0x6c8;
+       u1Byte          preVal0x6cc;
+       u1Byte          curVal0x6cc;
+       BOOLEAN         limited_dig;
+
+       // algorithm related
+       u1Byte          preAlgorithm;
+       u1Byte          curAlgorithm;
+       u1Byte          btStatus;
+       u1Byte          wifiChnlInfo[3];
+} COEX_DM_8723A_2ANT, *PCOEX_DM_8723A_2ANT;
+
+typedef struct _COEX_STA_8723A_2ANT{
+       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_2ANT_MAX][10];
+       u4Byte                                  btInfoC2hCnt[BT_INFO_SRC_8723A_2ANT_MAX];
+       BOOLEAN                                 bC2hBtInquiryPage;
+       u1Byte                                  btRetryCnt;
+       u1Byte                                  btInfoExt;
+       BOOLEAN                                 bHoldForStackOperation;
+       u1Byte                                  bHoldPeriodCnt;
+       // this is for c2h hang work-around
+       u4Byte                                  c2hHangDetectCnt;
+}COEX_STA_8723A_2ANT, *PCOEX_STA_8723A_2ANT;
+
+//===========================================
+// The following is interface which will notify coex module.
+//===========================================
+VOID
+EXhalbtc8723a2ant_InitHwConfig(
+       IN      PBTC_COEXIST            pBtCoexist
+       );
+VOID
+EXhalbtc8723a2ant_InitCoexDm(
+       IN      PBTC_COEXIST            pBtCoexist
+       );
+VOID
+EXhalbtc8723a2ant_IpsNotify(
+       IN      PBTC_COEXIST            pBtCoexist,
+       IN      u1Byte                  type
+       );
+VOID
+EXhalbtc8723a2ant_LpsNotify(
+       IN      PBTC_COEXIST            pBtCoexist,
+       IN      u1Byte                  type
+       );
+VOID
+EXhalbtc8723a2ant_ScanNotify(
+       IN      PBTC_COEXIST            pBtCoexist,
+       IN      u1Byte                  type
+       );
+VOID
+EXhalbtc8723a2ant_ConnectNotify(
+       IN      PBTC_COEXIST            pBtCoexist,
+       IN      u1Byte                  type
+       );
+VOID
+EXhalbtc8723a2ant_MediaStatusNotify(
+       IN      PBTC_COEXIST                    pBtCoexist,
+       IN      u1Byte                          type
+       );
+VOID
+EXhalbtc8723a2ant_SpecialPacketNotify(
+       IN      PBTC_COEXIST                    pBtCoexist,
+       IN      u1Byte                          type
+       );
+VOID
+EXhalbtc8723a2ant_HaltNotify(
+       IN      PBTC_COEXIST                    pBtCoexist
+       );
+VOID
+EXhalbtc8723a2ant_Periodical(
+       IN      PBTC_COEXIST                    pBtCoexist
+       );
+VOID
+EXhalbtc8723a2ant_BtInfoNotify(
+       IN      PBTC_COEXIST            pBtCoexist,
+       IN      pu1Byte                 tmpBuf,
+       IN      u1Byte                  length
+       );
+VOID
+EXhalbtc8723a2ant_StackOperationNotify(
+       IN      PBTC_COEXIST                    pBtCoexist,
+       IN      u1Byte                          type
+       );
+VOID
+EXhalbtc8723a2ant_DisplayCoexInfo(
+       IN      PBTC_COEXIST            pBtCoexist
+       );
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8723b1ant.c b/drivers/staging/rtl8821ae/btcoexist/halbtc8723b1ant.c
new file mode 100644 (file)
index 0000000..3414ba7
--- /dev/null
@@ -0,0 +1,4104 @@
+/***************************************************************
+ * Description:
+ *
+ * This file is for RTL8723B 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_8723b_1ant glcoex_dm_8723b_1ant;
+static struct coex_dm_8723b_1ant *coex_dm = &glcoex_dm_8723b_1ant;
+static struct coex_sta_8723b_1ant glcoex_sta_8723b_1ant;
+static struct coex_sta_8723b_1ant *coex_sta = &glcoex_sta_8723b_1ant;
+
+const char *const GLBtInfoSrc8723b1Ant[]={
+       "BT Info[wifi fw]",
+       "BT Info[bt rsp]",
+       "BT Info[bt auto report]",
+};
+
+u32 glcoex_ver_date_8723b_1ant = 20130906;
+u32 glcoex_ver_8723b_1ant = 0x45;
+
+/***************************************************************
+ * local function proto type if needed
+ ***************************************************************/
+/***************************************************************
+ * local function start with halbtc8723b1ant_
+ ***************************************************************/
+u8 halbtc8723b1ant_bt_rssi_state(u8 level_num, u8 rssi_thresh, u8 rssi_thresh1)
+{
+       s32 bt_rssi=0;
+       u8 bt_rssi_state = coex_sta->pre_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_8723B_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_8723B_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_8723B_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;
+}
+
+u8 halbtc8723b1ant_wifi_rssi_state(struct btc_coexist *btcoexist,
+                                  u8 index, u8 level_num,
+                                  u8 rssi_thresh, u8 rssi_thresh1)
+{
+       s32 wifi_rssi=0;
+       u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];
+
+       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_8723B_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_8723B_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_8723B_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 halbtc8723b1ant_updatera_mask(struct btc_coexist *btcoexist,
+                                  bool force_exec, u32 dis_rate_mask)
+{
+       coex_dm->curra_mask = dis_rate_mask;
+
+       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 halbtc8723b1ant_auto_rate_fallback_retry(struct btc_coexist *btcoexist,
+                                             bool force_exec, u8 type)
+{
+       bool wifi_under_bmode = false;
+
+       coex_dm->cur_arfr_type = type;
+
+       if (force_exec || (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) {
+               switch (coex_dm->cur_arfr_type) {
+               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_arfr_type = coex_dm->cur_arfr_type;
+}
+
+void halbtc8723b1ant_retry_limit(struct btc_coexist *btcoexist,
+                                bool force_exec, u8 type)
+{
+       coex_dm->cur_retry_limit_type = type;
+
+       if (force_exec || (coex_dm->pre_retry_limit_type !=
+                          coex_dm->cur_retry_limit_type)) {
+
+               switch (coex_dm->cur_retry_limit_type) {
+               case 0: /* normal mode */
+                       btcoexist->btc_write_2byte(btcoexist, 0x42a,
+                                                  coex_dm->backup_retry_limit);
+                       break;
+               case 1: /* retry limit=8 */
+                       btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type;
+}
+
+void halbtc8723b1ant_ampdu_maxtime(struct btc_coexist *btcoexist,
+                                  bool force_exec, u8 type)
+{
+       coex_dm->cur_ampdu_time_type = type;
+
+       if (force_exec || (coex_dm->pre_ampdu_time_type !=
+               coex_dm->cur_ampdu_time_type)) {
+               switch (coex_dm->cur_ampdu_time_type) {
+                       case 0: /* normal mode */
+                               btcoexist->btc_write_1byte(btcoexist, 0x456,
+                                               coex_dm->backup_ampdu_max_time);
+                               break;
+                       case 1: /* AMPDU timw = 0x38 * 32us */
+                               btcoexist->btc_write_1byte(btcoexist,
+                                                          0x456, 0x38);
+                               break;
+                       default:
+                               break;
+               }
+       }
+
+       coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type;
+}
+
+void halbtc8723b1ant_limited_tx(struct btc_coexist *btcoexist,
+                               bool force_exec, u8 ra_maskType, u8 arfr_type,
+                               u8 retry_limit_type, u8 ampdu_time_type)
+{
+       switch (ra_maskType) {
+       case 0: /* normal mode */
+               halbtc8723b1ant_updatera_mask(btcoexist, force_exec, 0x0);
+               break;
+       case 1: /* disable cck 1/2 */
+               halbtc8723b1ant_updatera_mask(btcoexist, force_exec,
+                                             0x00000003);
+               break;
+       /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4*/
+       case 2:
+               halbtc8723b1ant_updatera_mask(btcoexist, force_exec,
+                                             0x0001f1f7);
+               break;
+       default:
+               break;
+       }
+
+       halbtc8723b1ant_auto_rate_fallback_retry(btcoexist, force_exec,
+                                                arfr_type);
+       halbtc8723b1ant_retry_limit(btcoexist, force_exec, retry_limit_type);
+       halbtc8723b1ant_ampdu_maxtime(btcoexist, force_exec, ampdu_time_type);
+}
+
+void halbtc8723b1ant_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 rxAggSize = 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, &rxAggSize);
+       /* real update aggregation setting  */
+       btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
+}
+
+void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
+{
+       u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
+       u32 reg_hp_tx = 0, reg_hp_rx = 0;
+       u32 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;
+
+       /* reset counter */
+       btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+}
+
+void halbtc8723b1ant_query_bt_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 halbtc8723b1ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
+{
+       static bool pre_wifi_busy = false;
+       static bool pre_under_4way = false, pre_bt_hs_on = false;
+       bool wifi_busy = false, under_4way = false, bt_hs_on = 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_hs_on);
+       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_hs_on != pre_bt_hs_on) {
+                       pre_bt_hs_on = bt_hs_on;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+void halbtc8723b1ant_update_bt_link_info(struct btc_coexist *btcoexist)
+{
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+       bool bt_hs_on = false;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+       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_hs_on) {
+               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 halbtc8723b1ant_action_algorithm(struct btc_coexist *btcoexist)
+{
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+       bool bt_hs_on = false;
+       u8 algorithm = BT_8723B_1ANT_COEX_ALGO_UNDEFINED;
+       u8 numOfDiffProfile = 0;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+       if (!bt_link_info->bt_link_exist) {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], 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,
+                                 "[BTCoex], BT Profile = SCO only\n");
+                       algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
+               } else {
+                       if (bt_link_info->hid_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], BT Profile = HID only\n");
+                               algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
+                       } else if (bt_link_info->a2dp_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], BT Profile = A2DP only\n");
+                               algorithm = BT_8723B_1ANT_COEX_ALGO_A2DP;
+                       } else if (bt_link_info->pan_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "PAN(HS) only\n");
+                                       algorithm =
+                                               BT_8723B_1ANT_COEX_ALGO_PANHS;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "PAN(EDR) only\n");
+                                       algorithm =
+                                               BT_8723B_1ANT_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,
+                                         "[BTCoex], BT Profile = SCO + HID\n");
+                               algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
+                       } else if (bt_link_info->a2dp_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], BT Profile = "
+                                         "SCO + A2DP ==> SCO\n");
+                               algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
+                       } else if (bt_link_info->pan_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile "
+                                                 "= SCO + PAN(HS)\n");
+                                       algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile "
+                                                 "= SCO + PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       }
+               } else {
+                       if (bt_link_info->hid_exist &&
+                           bt_link_info->a2dp_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], BT Profile = "
+                                         "HID + A2DP\n");
+                               algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
+                       } else if (bt_link_info->hid_exist &&
+                                  bt_link_info->pan_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "HID + PAN(HS)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "HID + PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       } else if (bt_link_info->pan_exist &&
+                                  bt_link_info->a2dp_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "A2DP + PAN(HS)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "A2DP + PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_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,
+                                         "[BTCoex], BT Profile = "
+                                         "SCO + HID + A2DP ==> HID\n");
+                               algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
+                       } else if (bt_link_info->hid_exist &&
+                                  bt_link_info->pan_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "SCO + HID + PAN(HS)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "SCO + HID + PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       } else if (bt_link_info->pan_exist &&
+                                  bt_link_info->a2dp_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "SCO + A2DP + PAN(HS)\n");
+                                       algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = SCO + "
+                                                 "A2DP + PAN(EDR) ==> HID\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       }
+               } else {
+                       if (bt_link_info->hid_exist &&
+                           bt_link_info->pan_exist &&
+                           bt_link_info->a2dp_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "HID + A2DP + PAN(HS)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "HID + A2DP + PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_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_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], Error!!! "
+                                                 "BT Profile = SCO + "
+                                                 "HID + A2DP + PAN(HS)\n");
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], BT Profile = "
+                                                 "SCO + HID + A2DP + PAN(EDR)"
+                                                 "==>PAN(EDR)+HID\n");
+                                       algorithm =
+                                           BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       }
+               }
+       }
+
+       return algorithm;
+}
+
+bool halbtc8723b1ant_need_to_dec_bt_pwr(struct btc_coexist *btcoexist)
+{
+       bool ret = false;
+       bool bt_hs_on = false, wifi_connected = false;
+       s32 bt_hs_rssi = 0;
+       u8 bt_rssi_state;
+
+       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;
+
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 35, 0);
+
+       if (wifi_connected) {
+               if (bt_hs_on) {
+                       if (bt_hs_rssi > 37)
+                               ret = true;
+               } else {
+                       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
+                               ret = true;
+               }
+       }
+
+       return ret;
+}
+
+void halbtc8723b1ant_set_fw_dac_swing_level(struct btc_coexist *btcoexist,
+                                           u8 dac_swing_lvl)
+{
+       u8 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 halbtc8723b1ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist,
+                                      bool dec_bt_pwr)
+{
+       u8 h2c_parameter[1] = {0};
+
+       h2c_parameter[0] = 0;
+
+       if (dec_bt_pwr)
+               h2c_parameter[0] |= BIT1;
+
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+                 "[BTCoex], decrease Bt Power : %s, FW write 0x62=0x%x\n",
+                 (dec_bt_pwr? "Yes!!":"No!!"),h2c_parameter[0]);
+
+       btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
+}
+
+void halbtc8723b1ant_dec_bt_pwr(struct btc_coexist *btcoexist,
+                               bool force_exec, bool 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], bPreDecBtPwr=%d, bCurDecBtPwr=%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;
+       }
+       halbtc8723b1ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr);
+
+       coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr;
+}
+
+void halbtc8723b1ant_set_bt_auto_report(struct btc_coexist *btcoexist,
+                                       bool enable_auto_report)
+{
+       u8 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);
+}
+
+void halbtc8723b1ant_bt_auto_report(struct btc_coexist *btcoexist,
+                                   bool force_exec, bool 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], 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;
+       }
+       halbtc8723b1ant_set_bt_auto_report(btcoexist,
+                                          coex_dm->cur_bt_auto_report);
+
+       coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
+}
+
+void halbtc8723b1ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist,
+                                     bool force_exec, u8 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], 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;
+       }
+
+       halbtc8723b1ant_set_fw_dac_swing_level(btcoexist,
+                                              coex_dm->cur_fw_dac_swing_lvl);
+
+       coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
+}
+
+void halbtc8723b1ant_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, 0xffff7);
+       } 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 halbtc8723b1ant_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;
+       }
+       halbtc8723b1ant_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 halbtc8723b1ant_set_sw_penalty_tx_rate_adaptive(
+                                       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 halbtc8723b1ant_low_penalty_ra(struct btc_coexist *btcoexist,
+                                   bool force_exec, bool low_penalty_ra)
+{
+       coex_dm->cur_low_penalty_ra = low_penalty_ra;
+
+       if (!force_exec) {
+               if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
+                       return;
+       }
+       halbtc8723b1ant_set_sw_penalty_tx_rate_adaptive(btcoexist,
+                                               coex_dm->cur_low_penalty_ra);
+
+       coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
+}
+
+void halbtc8723b1ant_set_dac_swing_reg(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 halbtc8723b1ant_set_sw_full_time_dac_swing(struct btc_coexist *btcoexist,
+                                               bool sw_dac_swing_on,
+                                               u32 sw_dac_swing_lvl)
+{
+       if (sw_dac_swing_on)
+               halbtc8723b1ant_set_dac_swing_reg(btcoexist, sw_dac_swing_lvl);
+       else
+               halbtc8723b1ant_set_dac_swing_reg(btcoexist, 0x18);
+}
+
+
+void halbtc8723b1ant_dac_swing(struct btc_coexist *btcoexist, bool force_exec,
+                              bool dac_swing_on, u32 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], bPreDacSwingOn=%d, preDacSwingLvl=0x%x, "
+                         "bCurDacSwingOn=%d, curDacSwingLvl=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;
+       }
+       mdelay(30);
+       halbtc8723b1ant_set_sw_full_time_dac_swing(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 halbtc8723b1ant_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, 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 halbtc8723b1ant_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_backoff = adc_backoff;
+
+       if (!force_exec) {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+                         "[BTCoex], bPreAdcBackOff=%d, bCurAdcBackOff=%d\n",
+                         coex_dm->pre_adc_backoff, coex_dm->cur_adc_backoff);
+
+               if(coex_dm->pre_adc_backoff == coex_dm->cur_adc_backoff)
+                       return;
+       }
+       halbtc8723b1ant_set_adc_backoff(btcoexist, coex_dm->cur_adc_backoff);
+
+       coex_dm->pre_adc_backoff =
+               coex_dm->cur_adc_backoff;
+}
+
+void halbtc8723b1ant_set_agc_table(struct btc_coexist *btcoexist,
+                                  bool adc_table_en)
+{
+       u8 rssi_adjust_val = 0;
+
+       btcoexist->btc_set_rf_reg(btcoexist,
+               BTC_RF_A, 0xef, 0xfffff, 0x02000);
+       if (adc_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 halbtc8723b1ant_agc_table(struct btc_coexist *btcoexist,
+                              bool force_exec, bool adc_table_en)
+{
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
+                 "[BTCoex], %s %s Agc Table\n",
+                 (force_exec ? "force to" : ""),
+                 (adc_table_en ? "Enable" : "Disable"));
+       coex_dm->cur_agc_table_en = adc_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;
+       }
+       halbtc8723b1ant_set_agc_table(btcoexist, adc_table_en);
+
+       coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en;
+}
+
+void halbtc8723b1ant_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 halbtc8723b1ant_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,"
+                 " 0x6c4=0x%x, 0x6cc=0x%x\n", (force_exec ? "force to" : ""),
+                 val0x6c0, val0x6c4, val0x6cc);
+       coex_dm->cur_val0x6c0 = val0x6c0;
+       coex_dm->cur_val0x6c4 = val0x6c4;
+       coex_dm->cur_val0x6c8 = val0x6c8;
+       coex_dm->cur_val0x6cc = val0x6cc;
+
+       if (!force_exec) {
+               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;
+       }
+       halbtc8723b1ant_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 halbtc8723b1ant_coex_table_with_type(struct btc_coexist *btcoexist,
+                                         bool force_exec, u8 type)
+{
+       switch (type) {
+       case 0:
+               halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+                                          0x55555555, 0xffffff, 0x3);
+               break;
+       case 1:
+               halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+                                          0x5a5a5a5a, 0xffffff, 0x3);
+               break;
+       case 2:
+               halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
+                                          0x5a5a5a5a, 0xffffff, 0x3);
+               break;
+       case 3:
+               halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+                                          0xaaaaaaaa, 0xffffff, 0x3);
+               break;
+       case 4:
+               halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+                                          0x5aaa5aaa, 0xffffff, 0x3);
+               break;
+       case 5:
+               halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
+                                          0xaaaa5a5a, 0xffffff, 0x3);
+               break;
+       case 6:
+               halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
+                                          0xaaaa5a5a, 0xffffff, 0x3);
+               break;
+       case 7:
+               halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5afa5afa,
+                                          0x5afa5afa, 0xffffff, 0x3);
+               break;
+       default:
+               break;
+       }
+}
+
+void halbtc8723b1ant_SetFwIgnoreWlanAct(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 halbtc8723b1ant_ignore_wlan_act(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, "
+                         "bCurIgnoreWlanAct = %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;
+       }
+       halbtc8723b1ant_SetFwIgnoreWlanAct(btcoexist, enable);
+
+       coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
+}
+
+void halbtc8723b1ant_set_fw_ps_tdma(struct btc_coexist *btcoexist,
+                                   u8 byte1, u8 byte2, u8 byte3,
+                                   u8 byte4, u8 byte5)
+{
+       u8 h2c_parameter[5] = {0};
+       u8 real_byte1 = byte1, real_byte5 = byte5;
+       bool ap_enable = false;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+                          &ap_enable);
+
+       if (ap_enable) {
+               if ((byte1 & BIT4) && !(byte1 & BIT5)) {
+                       BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                                 "[BTCoex], FW for 1Ant AP mode\n");
+                       real_byte1 &= ~BIT4;
+                       real_byte1 |= BIT5;
+
+                       real_byte5 |= BIT5;
+                       real_byte5 &= ~BIT6;
+               }
+       }
+
+       h2c_parameter[0] = real_byte1;
+       h2c_parameter[1] = byte2;
+       h2c_parameter[2] = byte3;
+       h2c_parameter[3] = byte4;
+       h2c_parameter[4] = real_byte5;
+
+       coex_dm->ps_tdma_para[0] = real_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] = real_byte5;
+
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+                 "[BTCoex], PS-TDMA H2C cmd =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 halbtc8723b1ant_SetLpsRpwm(struct btc_coexist *btcoexist,
+                               u8 lps_val, u8 rpwm_val)
+{
+       u8 lps = lps_val;
+       u8 rpwm = rpwm_val;
+
+       btcoexist->btc_set(btcoexist, BTC_SET_U1_1ANT_LPS, &lps);
+       btcoexist->btc_set(btcoexist, BTC_SET_U1_1ANT_RPWM, &rpwm);
+}
+
+void halbtc8723b1ant_LpsRpwm(struct btc_coexist *btcoexist, bool force_exec,
+                            u8 lps_val, u8 rpwm_val)
+{
+
+       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], LPS-RxBeaconMode=0x%x , LPS-RPWM=0x%x!!\n",
+                         coex_dm->cur_lps, coex_dm->cur_rpwm);
+
+               if ((coex_dm->pre_lps == coex_dm->cur_lps) &&
+                   (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) {
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+                                 "[BTCoex], LPS-RPWM_Last=0x%x"
+                                 " , LPS-RPWM_Now=0x%x!!\n",
+                                 coex_dm->pre_rpwm, coex_dm->cur_rpwm);
+
+                       return;
+               }
+       }
+       halbtc8723b1ant_SetLpsRpwm(btcoexist, lps_val, rpwm_val);
+
+       coex_dm->pre_lps = coex_dm->cur_lps;
+       coex_dm->pre_rpwm = coex_dm->cur_rpwm;
+}
+
+void halbtc8723b1ant_sw_mechanism1(struct btc_coexist *btcoexist,
+                                  bool shrink_rx_lpf, bool low_penalty_ra,
+                                  bool limited_dig, bool bt_lna_constrain)
+{
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
+                 "[BTCoex], SM1[ShRf/ LpRA/ LimDig/ btLna] = %d %d %d %d\n",
+                 shrink_rx_lpf, low_penalty_ra, limited_dig, bt_lna_constrain);
+
+       halbtc8723b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
+}
+
+void halbtc8723b1ant_sw_mechanism2(struct btc_coexist *btcoexist,
+                                  bool agc_table_shift, bool adc_backoff,
+                                  bool sw_dac_swing, u32 dac_swing_lvl)
+{
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
+                 "[BTCoex], SM2[AgcT/ AdcB/ SwDacSwing(lvl)] = %d %d %d\n",
+                 agc_table_shift, adc_backoff, sw_dac_swing);
+}
+
+void halbtc8723b1ant_SetAntPath(struct btc_coexist *btcoexist,
+                               u8 ant_pos_type, bool init_hw_cfg,
+                               bool wifi_off)
+{
+       struct btc_board_info *board_info = &btcoexist->board_info;
+       u32 fw_ver = 0, u32tmp = 0;
+       bool pg_ext_switch = false;
+       bool use_ext_switch = false;
+       u8 h2c_parameter[2] = {0};
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch);
+       /* [31:16]=fw ver, [15:0]=fw sub ver */
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
+
+
+       if ((fw_ver < 0xc0000) || pg_ext_switch)
+               use_ext_switch = true;
+
+       if (init_hw_cfg){
+               /*BT select s0/s1 is controlled by WiFi */
+               btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1);
+
+               /*Force GNT_BT to Normal */
+               btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
+       } else if (wifi_off) {
+               /*Force GNT_BT to High */
+               btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3);
+               /*BT select s0/s1 is controlled by BT */
+               btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0);
+
+               /* 0x4c[24:23]=00, Set Antenna control by BT_RFE_CTRL
+                * BT Vendor 0xac=0xf002 */
+               u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+               u32tmp &= ~BIT23;
+               u32tmp &= ~BIT24;
+               btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
+       }
+
+       if (use_ext_switch) {
+               if (init_hw_cfg) {
+                       /* 0x4c[23]=0, 0x4c[24]=1  Antenna control by WL/BT */
+                       u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+                       u32tmp &= ~BIT23;
+                       u32tmp |= BIT24;
+                       btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
+
+                       if (board_info->btdm_ant_pos ==
+                           BTC_ANTENNA_AT_MAIN_PORT) {
+                               /* Main Ant to  BT for IPS case 0x4c[23]=1 */
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x64, 0x1,
+                                                                  0x1);
+
+                               /*tell firmware "no antenna inverse"*/
+                               h2c_parameter[0] = 0;
+                               h2c_parameter[1] = 1;  /*ext switch type*/
+                               btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
+                                                       h2c_parameter);
+                       } else {
+                               /*Aux Ant to  BT for IPS case 0x4c[23]=1 */
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x64, 0x1,
+                                                                  0x0);
+
+                               /*tell firmware "antenna inverse"*/
+                               h2c_parameter[0] = 1;
+                               h2c_parameter[1] = 1;  /*ext switch type*/
+                               btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
+                                                       h2c_parameter);
+                       }
+               }
+
+               /* fixed internal switch first*/
+               /* fixed internal switch S1->WiFi, S0->BT*/
+               if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
+                       btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
+               else/* fixed internal switch S0->WiFi, S1->BT*/
+                       btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
+
+               /* ext switch setting */
+               switch (ant_pos_type) {
+               case BTC_ANT_PATH_WIFI:
+                       if (board_info->btdm_ant_pos ==
+                           BTC_ANTENNA_AT_MAIN_PORT)
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x92c, 0x3,
+                                                                  0x1);
+                       else
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x92c, 0x3,
+                                                                  0x2);
+                       break;
+               case BTC_ANT_PATH_BT:
+                       if (board_info->btdm_ant_pos ==
+                           BTC_ANTENNA_AT_MAIN_PORT)
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x92c, 0x3,
+                                                                  0x2);
+                       else
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x92c, 0x3,
+                                                                  0x1);
+                       break;
+               default:
+               case BTC_ANT_PATH_PTA:
+                       if (board_info->btdm_ant_pos ==
+                           BTC_ANTENNA_AT_MAIN_PORT)
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x92c, 0x3,
+                                                                  0x1);
+                       else
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x92c, 0x3,
+                                                                  0x2);
+                       break;
+               }
+
+       } else {
+               if (init_hw_cfg) {
+                       /* 0x4c[23]=1, 0x4c[24]=0  Antenna control by 0x64*/
+                       u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+                       u32tmp |= BIT23;
+                       u32tmp &= ~BIT24;
+                       btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
+
+                       if (board_info->btdm_ant_pos ==
+                           BTC_ANTENNA_AT_MAIN_PORT) {
+                               /*Main Ant to  WiFi for IPS case 0x4c[23]=1*/
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x64, 0x1,
+                                                                  0x0);
+
+                               /*tell firmware "no antenna inverse"*/
+                               h2c_parameter[0] = 0;
+                               h2c_parameter[1] = 0;  /*internal switch type*/
+                               btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
+                                                       h2c_parameter);
+                       } else {
+                               /*Aux Ant to  BT for IPS case 0x4c[23]=1*/
+                               btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                                  0x64, 0x1,
+                                                                  0x1);
+
+                               /*tell firmware "antenna inverse"*/
+                               h2c_parameter[0] = 1;
+                               h2c_parameter[1] = 0;  /*internal switch type*/
+                               btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
+                                                       h2c_parameter);
+                       }
+               }
+
+               /* fixed external switch first*/
+               /*Main->WiFi, Aux->BT*/
+               if(board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
+                       btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
+                                                          0x3, 0x1);
+               else/*Main->BT, Aux->WiFi */
+                       btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
+                                                          0x3, 0x2);
+
+               /* internal switch setting*/
+               switch (ant_pos_type) {
+               case BTC_ANT_PATH_WIFI:
+                       if(board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
+                               btcoexist->btc_write_2byte(btcoexist, 0x948,
+                                                          0x0);
+                       else
+                               btcoexist->btc_write_2byte(btcoexist, 0x948,
+                                                          0x280);
+                       break;
+               case BTC_ANT_PATH_BT:
+                       if(board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
+                               btcoexist->btc_write_2byte(btcoexist, 0x948,
+                                                          0x280);
+                       else
+                               btcoexist->btc_write_2byte(btcoexist, 0x948,
+                                                          0x0);
+                       break;
+               default:
+               case BTC_ANT_PATH_PTA:
+                       if(board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
+                               btcoexist->btc_write_2byte(btcoexist, 0x948,
+                                                          0x200);
+                       else
+                               btcoexist->btc_write_2byte(btcoexist, 0x948,
+                                                          0x80);
+                       break;
+               }
+       }
+}
+
+void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec,
+                            bool turn_on, u8 type)
+{
+       bool wifi_busy = false;
+       u8 rssi_adjust_val = 0;
+
+       coex_dm->cur_ps_tdma_on = turn_on;
+       coex_dm->cur_ps_tdma = type;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+       if (!force_exec) {
+               if (coex_dm->cur_ps_tdma_on)
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+                                 "[BTCoex], ******** TDMA(on, %d) *********\n",
+                                 coex_dm->cur_ps_tdma);
+               else
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+                                 "[BTCoex], ******** TDMA(off, %d) ********\n",
+                                 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:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a,
+                                                      0x1a, 0x0, 0x50);
+                       break;
+               case 1:
+                       if (wifi_busy)
+                               halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51,
+                                                              0x3a, 0x03,
+                                                              0x10, 0x50);
+                       else
+                               halbtc8723b1ant_set_fw_ps_tdma(btcoexist,0x51,
+                                                              0x3a, 0x03,
+                                                              0x10, 0x51);
+
+                       rssi_adjust_val = 11;
+                       break;
+               case 2:
+                       if (wifi_busy)
+                               halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51,
+                                                              0x2b, 0x03,
+                                                              0x10, 0x50);
+                       else
+                               halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51,
+                                                              0x2b, 0x03,
+                                                              0x10, 0x51);
+                       rssi_adjust_val = 14;
+                       break;
+               case 3:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1d,
+                                                      0x1d, 0x0, 0x52);
+                       break;
+               case 4:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
+                                                      0x3, 0x14, 0x0);
+                       rssi_adjust_val = 17;
+                       break;
+               case 5:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15,
+                                                      0x3, 0x11, 0x10);
+                       break;
+               case 6:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x20,
+                                                      0x3, 0x11, 0x13);
+                       break;
+               case 7:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc,
+                                                      0x5, 0x0, 0x0);
+                       break;
+               case 8:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
+                                                      0x3, 0x10, 0x0);
+                       break;
+               case 9:
+                       if(wifi_busy)
+                               halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51,
+                                                              0x21, 0x3,
+                                                              0x10, 0x50);
+                       else
+                               halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51,
+                                                              0x21, 0x3,
+                                                              0x10, 0x50);
+                       rssi_adjust_val = 18;
+                       break;
+               case 10:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
+                                                      0xa, 0x0, 0x40);
+                       break;
+               case 11:
+                       if (wifi_busy)
+                               halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51,
+                                                              0x15, 0x03,
+                                                              0x10, 0x50);
+                       else
+                               halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51,
+                                                              0x15, 0x03,
+                                                              0x10, 0x50);
+                       rssi_adjust_val = 20;
+                       break;
+               case 12:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a,
+                                                      0x0a, 0x0, 0x50);
+                       break;
+               case 13:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15,
+                                                      0x15, 0x0, 0x50);
+                       break;
+               case 14:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21,
+                                                      0x3, 0x10, 0x52);
+                       break;
+               case 15:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
+                                                      0x3, 0x8, 0x0);
+                       break;
+               case 16:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
+                                                      0x3, 0x10, 0x0);
+                       rssi_adjust_val = 18;
+                       break;
+               case 18:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
+                                                      0x3, 0x10, 0x0);
+                       rssi_adjust_val = 14;
+                       break;
+               case 20:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35,
+                                                      0x03, 0x11, 0x10);
+                       break;
+               case 21:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15,
+                                                      0x03, 0x11, 0x10);
+                       break;
+               case 22:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25,
+                                                      0x03, 0x11, 0x10);
+                       break;
+               case 23:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
+                                                      0x3, 0x31, 0x18);
+                       rssi_adjust_val = 22;
+                       break;
+               case 24:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15,
+                                                      0x3, 0x31, 0x18);
+                       rssi_adjust_val = 22;
+                       break;
+               case 25:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
+                                                      0x3, 0x31, 0x18);
+                       rssi_adjust_val = 22;
+                       break;
+               case 26:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
+                                                      0x3, 0x31, 0x18);
+                       rssi_adjust_val = 22;
+                       break;
+               case 27:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
+                                                      0x3, 0x31, 0x98);
+                       rssi_adjust_val = 22;
+                       break;
+               case 28:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25,
+                                                      0x3, 0x31, 0x0);
+                       break;
+               case 29:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a,
+                                                      0x1a, 0x1, 0x10);
+                       break;
+               case 30:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x14,
+                                                      0x3, 0x10, 0x50);
+                       break;
+               case 31:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a,
+                                                      0x1a, 0, 0x58);
+                       break;
+               case 32:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0xa,
+                                                      0x3, 0x10, 0x0);
+                       break;
+               case 33:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x25,
+                                                      0x3, 0x30, 0x90);
+                       break;
+               case 34:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a,
+                                                      0x1a, 0x0, 0x10);
+                       break;
+               case 35:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a,
+                                                      0x1a, 0x0, 0x10);
+                       break;
+               case 36:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12,
+                                                      0x3, 0x14, 0x50);
+                       break;
+               /* SoftAP only with no sta associated,BT disable ,
+                * TDMA mode for power saving
+                * here softap mode screen off will cost 70-80mA for phone */
+               case 40:
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x23, 0x18,
+                                                      0x00, 0x10, 0x24);
+                       break;
+               }
+       } else {
+               switch (type) {
+               case 8: /*PTA Control */
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0,
+                                                      0x0, 0x0, 0x0);
+                       halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_PTA,
+                                                  false, false);
+                       break;
+               case 0:
+               default:  /*Software control, Antenna at BT side */
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0,
+                                                      0x0, 0x0, 0x0);
+                       halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT,
+                                                  false, false);
+                       break;
+               case 9:   /*Software control, Antenna at WiFi side */
+                       halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0,
+                                                      0x0, 0x0, 0x0);
+                       halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_WIFI,
+                                                  false, false);
+                       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 halbtc8723b1ant_coex_alloff(struct btc_coexist *btcoexist)
+{
+       /* fw all off */
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+       halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       /* sw all off */
+       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false, false, false);
+       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
+
+
+       /* hw all off */
+       halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
+bool halbtc8723b1ant_is_common_action(struct btc_coexist *btcoexist)
+{
+       bool commom = false, wifi_connected = false;
+       bool 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);
+
+       if (!wifi_connected &&
+           BT_8723B_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");
+               halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+               halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                             false, false);
+               halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                             false, 0x18);
+
+               commom = true;
+       } else if (wifi_connected &&
+                  (BT_8723B_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");
+               halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+               halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                             false, false);
+               halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                             false, 0x18);
+
+               commom = true;
+       } else if (!wifi_connected &&
+                  (BT_8723B_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");
+               halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+               halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                             false, false);
+               halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                             false, 0x18);
+
+               commom = true;
+       } else if (wifi_connected &&
+                  (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE ==
+                   coex_dm->bt_status)) {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], Wifi connected + BT connected-idle!!\n");
+               halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+               halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                             false, false);
+               halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                             false, 0x18);
+
+               commom = true;
+       } else if (!wifi_connected &&
+                  (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE !=
+                   coex_dm->bt_status)) {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                       ("[BTCoex], Wifi non connected-idle + BT Busy!!\n"));
+               halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+               halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                             false, false);
+               halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                             false, 0x18);
+
+               commom = true;
+       } else {
+               if (wifi_busy)
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Wifi Connected-Busy"
+                                 " + BT Busy!!\n");
+               else
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Wifi Connected-Idle"
+                                 " + BT Busy!!\n");
+
+               commom = false;
+       }
+
+       return commom;
+}
+
+
+void halbtc8723b1ant_tdma_duration_adjust_for_acl(struct btc_coexist *btcoexist,
+                                                 u8 wifi_status)
+{
+       static s32 up, dn, m, n, wait_count;
+       /* 0: no change, +1: increase WiFi duration,
+        * -1: decrease WiFi duration */
+       s32 result;
+       u8 retry_count = 0, bt_info_ext;
+       static bool pre_wifi_busy = false;
+       bool wifi_busy = false;
+
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
+                 "[BTCoex], TdmaDurationAdjustForAcl()\n");
+
+       if (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY == wifi_status)
+               wifi_busy = true;
+       else
+               wifi_busy = false;
+
+       if ((BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN ==
+                                                        wifi_status) ||
+           (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifi_status) ||
+           (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifi_status)) {
+               if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 &&
+                   coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) {
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               true, 9);
+                       coex_dm->ps_tdma_du_adj_type = 9;
+
+                       up = 0;
+                       dn = 0;
+                       m = 1;
+                       n = 3;
+                       result = 0;
+                       wait_count = 0;
+               }
+               return;
+       }
+
+       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");
+
+               halbtc8723b1ant_ps_tdma(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;
+               result = 0;
+               wait_count++;
+               /* no retry in the last 2-second duration */
+               if (retry_count == 0) {
+                       up++;
+                       dn--;
+
+                       if (dn <= 0)
+                               dn = 0;
+
+                       if (up >= n) {
+                               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) {
+                       up--;
+                       dn++;
+
+                       if (up <= 0)
+                               up = 0;
+
+                       if (dn == 2) {
+                               if (wait_count <= 2)
+                                       m++;
+                               else
+                                       m = 1;
+
+                               if (m >= 20)
+                                       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 {
+                       if (wait_count == 1)
+                               m++;
+                       else
+                               m = 1;
+
+                       if (m >= 20)
+                               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_8723B_1ANT_A2DP_BASIC_RATE(bt_info_ext)) &&
+                           ((coex_dm->cur_ps_tdma == 1) ||
+                            (coex_dm->cur_ps_tdma == 2))) {
+                               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 9);
+                               coex_dm->ps_tdma_du_adj_type = 9;
+                       } else if (coex_dm->cur_ps_tdma == 1) {
+                               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 2);
+                               coex_dm->ps_tdma_du_adj_type = 2;
+                       } else if (coex_dm->cur_ps_tdma == 2) {
+                               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 9);
+                               coex_dm->ps_tdma_du_adj_type = 9;
+                       } else if (coex_dm->cur_ps_tdma == 9) {
+                               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 11);
+                               coex_dm->ps_tdma_du_adj_type = 11;
+                       }
+               } else if(result == 1) {
+                       if ((BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(bt_info_ext)) &&
+                           ((coex_dm->cur_ps_tdma == 1) ||
+                            (coex_dm->cur_ps_tdma == 2))) {
+                               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 9);
+                               coex_dm->ps_tdma_du_adj_type = 9;
+                       } else if (coex_dm->cur_ps_tdma == 11) {
+                               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 9);
+                               coex_dm->ps_tdma_du_adj_type = 9;
+                       } else if (coex_dm->cur_ps_tdma == 9) {
+                               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 2);
+                               coex_dm->ps_tdma_du_adj_type = 2;
+                       } else if (coex_dm->cur_ps_tdma == 2) {
+                               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 1);
+                               coex_dm->ps_tdma_du_adj_type = 1;
+                       }
+               } else {          /*no change */
+                       /*if busy / idle change */
+                       if (wifi_busy != pre_wifi_busy) {
+                               pre_wifi_busy = wifi_busy;
+                               halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC,
+                                                       true,
+                                                       coex_dm->cur_ps_tdma);
+                       }
+
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+                                 "[BTCoex],********* TDMA(on, %d) ********\n",
+                                 coex_dm->cur_ps_tdma);
+               }
+
+               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 */
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+                                               coex_dm->ps_tdma_du_adj_type);
+               }
+       }
+}
+
+u8 halbtc8723b1ant_ps_tdma_type_by_wifi_rssi(s32 wifi_rssi, s32 pre_wifi_rssi,
+                                            u8 wifi_rssi_thresh)
+{
+       u8 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 halbtc8723b1ant_PsTdmaCheckForPowerSaveState(struct btc_coexist *btcoexist,
+                                                 bool new_ps_state)
+{
+       u8 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 */
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               false, 0);
+               }
+       } else {        /* NO PS state */
+               if (new_ps_state) {
+                       /* will enter LPS state, turn off psTdma first */
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               false, 0);
+               } else {
+                       /* keep state under NO PS state, do nothing. */
+               }
+       }
+}
+
+void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist,
+                                     u8 ps_type, u8 lps_val,
+                                     u8 rpwm_val)
+{
+       bool low_pwr_disable = false;
+
+       switch (ps_type) {
+       case BTC_PS_WIFI_NATIVE:
+               /* recover to original 32k low power setting */
+               low_pwr_disable = false;
+               btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+                                  &low_pwr_disable);
+               btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
+               break;
+       case BTC_PS_LPS_ON:
+               halbtc8723b1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+               halbtc8723b1ant_LpsRpwm(btcoexist, NORMAL_EXEC, lps_val,
+                                       rpwm_val);
+               /* when coex force to enter LPS, do not enter 32k low power. */
+               low_pwr_disable = true;
+               btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+                                  &low_pwr_disable);
+               /* power save must executed before psTdma.       */
+               btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+               break;
+       case BTC_PS_LPS_OFF:
+               halbtc8723b1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+               btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+               break;
+       default:
+               break;
+       }
+}
+
+void halbtc8723b1ant_action_wifi_only(struct btc_coexist *btcoexist)
+{
+       halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 9);
+}
+
+void halbtc8723b1ant_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");
+                       halbtc8723b1ant_action_wifi_only(btcoexist);
+               }
+       }
+       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 {
+                       btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS,
+                                          NULL);
+                       btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS,
+                                          NULL);
+               }
+       }
+}
+
+/***************************************************
+ *
+ *     Software Coex Mechanism start
+ *
+ ***************************************************/
+/* SCO only or SCO+PAN(HS) */
+void halbtc8723b1ant_action_sco(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state =
+               halbtc8723b1ant_wifi_rssi_state(btcoexist, 0, 2, 25, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+
+void halbtc8723b1ant_action_hid(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
+void halbtc8723b1ant_action_a2dp(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
+       u32 wifi_bw;
+
+       bt_info_ext = coex_sta->bt_info_ext;
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b1ant_action_pan_edr(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+
+/* PAN(HS) only */
+void halbtc8723b1ant_action_pan_hs(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(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))
+                       halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
+                                                  false);
+               else
+                       halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
+                                                  false);
+
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* fw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
+                       halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
+                                                  false);
+               else
+                       halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
+                                                  false);
+
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+/*PAN(EDR)+A2DP */
+void halbtc8723b1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
+       u32 wifi_bw;
+
+       bt_info_ext = coex_sta->bt_info_ext;
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+/* HID+A2DP+PAN(EDR) */
+void halbtc8723b1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
+       u32 wifi_bw;
+
+       bt_info_ext = coex_sta->bt_info_ext;
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
+       u32 wifi_bw;
+
+       bt_info_ext = coex_sta->bt_info_ext;
+       wifi_rssi_state = halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 25, 0);
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 50, 0);
+
+       if (halbtc8723b1ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b1ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+       else
+               halbtc8723b1ant_dec_bt_pwr(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)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               /* sw mechanism */
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b1ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b1ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+/*****************************************************
+ *
+ *     Non-Software Coex Mechanism start
+ *
+ *****************************************************/
+void halbtc8723b1ant_action_hs(struct btc_coexist *btcoexist)
+{
+       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
+       halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2);
+}
+
+void halbtc8723b1ant_action_bt_inquiry(struct btc_coexist *btcoexist)
+{
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+       bool wifi_connected = false, ap_enable = false;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+                          &ap_enable);
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+                          &wifi_connected);
+
+       if (!wifi_connected) {
+               halbtc8723b1ant_power_save_state(btcoexist,
+                                                BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+       } else if (bt_link_info->sco_exist || bt_link_info->hid_only) {
+               /* SCO/HID-only busy */
+               halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+                                                0x0, 0x0);
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+       } else {
+               if (ap_enable)
+                       halbtc8723b1ant_power_save_state(btcoexist,
+                                                        BTC_PS_WIFI_NATIVE,
+                                                        0x0, 0x0);
+               else
+                       halbtc8723b1ant_power_save_state(btcoexist,
+                                                        BTC_PS_LPS_ON,
+                                                        0x50, 0x4);
+
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 30);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+       }
+}
+
+void halbtc8723b1ant_action_bt_sco_hid_only_busy(struct btc_coexist * btcoexist,
+                                                u8 wifi_status)
+{
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+       bool wifi_connected = false;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+                          &wifi_connected);
+
+       /* tdma and coex table */
+
+       if (bt_link_info->sco_exist) {
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+       } else { /* HID */
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+       }
+}
+
+void halbtc8723b1ant_action_wifi_connected_bt_acl_busy(
+                                       struct btc_coexist *btcoexist,
+                                       u8 wifi_status)
+{
+       u8 bt_rssi_state;
+
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+       bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 28, 0);
+
+       if (bt_link_info->hid_only) {  /*HID */
+               halbtc8723b1ant_action_bt_sco_hid_only_busy(btcoexist,
+                                                           wifi_status);
+               coex_dm->auto_tdma_adjust = false;
+               return;
+       } else if (bt_link_info->a2dp_only) { /*A2DP */
+               if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                        halbtc8723b1ant_tdma_duration_adjust_for_acl(btcoexist,
+                                                                  wifi_status);
+               } else { /*for low BT RSSI */
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               true, 11);
+                       coex_dm->auto_tdma_adjust = false;
+               }
+
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+       } else if (bt_link_info->hid_exist &&
+                       bt_link_info->a2dp_exist) { /*HID+A2DP */
+               if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               true, 14);
+                       coex_dm->auto_tdma_adjust = false;
+               } else { /*for low BT RSSI*/
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               true, 14);
+                       coex_dm->auto_tdma_adjust = false;
+               }
+
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
+        /*PAN(OPP,FTP), HID+PAN(OPP,FTP) */
+       } else if (bt_link_info->pan_only ||
+                  (bt_link_info->hid_exist && bt_link_info->pan_exist)) {
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
+               coex_dm->auto_tdma_adjust = false;
+        /*A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP)*/
+       } else if ((bt_link_info->a2dp_exist && bt_link_info->pan_exist) ||
+                  (bt_link_info->hid_exist && bt_link_info->a2dp_exist &&
+                   bt_link_info->pan_exist)) {
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+               coex_dm->auto_tdma_adjust = false;
+       } else {
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+               coex_dm->auto_tdma_adjust = false;
+       }
+}
+
+void halbtc8723b1ant_action_wifi_not_connected(struct btc_coexist *btcoexist)
+{
+       /* power save state */
+       halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+                                        0x0, 0x0);
+
+       /* tdma and coex table */
+       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+       halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
+void halbtc8723b1ant_action_wifi_not_connected_asso_auth_scan(
+                                               struct btc_coexist *btcoexist)
+{
+       halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+                                        0x0, 0x0);
+
+       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
+       halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+}
+
+void halbtc8723b1ant_ActionWifiConnectedScan(struct btc_coexist *btcoexist)
+{
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+       halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+                                        0x0, 0x0);
+
+       /* tdma and coex table */
+       if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
+               if (bt_link_info->a2dp_exist &&
+                   bt_link_info->pan_exist) {
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               true, 22);
+                       halbtc8723b1ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 1);
+               } else {
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+               }
+       } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+                  (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
+                   coex_dm->bt_status)) {
+               halbtc8723b1ant_action_bt_sco_hid_only_busy(btcoexist,
+                               BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN);
+       } else {
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+       }
+}
+
+void halbtc8723b1ant_action_wifi_connected_special_packet(
+                                               struct btc_coexist *btcoexist)
+{
+       bool hs_connecting = false;
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting);
+
+       halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+                                        0x0, 0x0);
+
+       /* tdma and coex table */
+       if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
+               if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               true, 22);
+                       halbtc8723b1ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 1);
+               } else {
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               true, 20);
+                       halbtc8723b1ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 1);
+               }
+       } else {
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
+               halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+       }
+}
+
+void halbtc8723b1ant_action_wifi_connected(struct btc_coexist *btcoexist)
+{
+       bool wifi_busy = false;
+       bool scan = false, link = false, roam = false;
+       bool under_4way = false, ap_enable = false;
+
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                 "[BTCoex], CoexForWifiConnect()===>\n");
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+                          &under_4way);
+       if (under_4way) {
+               halbtc8723b1ant_action_wifi_connected_special_packet(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_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) {
+               halbtc8723b1ant_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_AP_MODE_ENABLE,
+                          &ap_enable);
+       /* power save state */
+       if (!ap_enable &&
+           BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status &&
+           !btcoexist->bt_link_info.hid_only)
+               halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_LPS_ON,
+                                                0x50, 0x4);
+       else
+               halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+                                                0x0, 0x0);
+
+       /* tdma and coex table */
+       btcoexist->btc_get(btcoexist,
+               BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+       if (!wifi_busy) {
+               if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
+                       halbtc8723b1ant_action_wifi_connected_bt_acl_busy(btcoexist,
+                                     BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE);
+               } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY ==
+                                               coex_dm->bt_status) ||
+                          (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
+                                               coex_dm->bt_status)) {
+                       halbtc8723b1ant_action_bt_sco_hid_only_busy(btcoexist,
+                                    BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE);
+               } else {
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                               false, 8);
+                       halbtc8723b1ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 2);
+               }
+       } else {
+               if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
+                       halbtc8723b1ant_action_wifi_connected_bt_acl_busy(btcoexist,
+                                   BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY);
+               } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY ==
+                                               coex_dm->bt_status) ||
+                          (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
+                                               coex_dm->bt_status)) {
+                       halbtc8723b1ant_action_bt_sco_hid_only_busy(btcoexist,
+                                   BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY);
+               } else {
+                       halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+                       halbtc8723b1ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 2);
+               }
+       }
+}
+
+void halbtc8723b1ant_run_sw_coexist_mechanism(struct btc_coexist *btcoexist)
+{
+       u8 algorithm = 0;
+
+       algorithm = halbtc8723b1ant_action_algorithm(btcoexist);
+       coex_dm->cur_algorithm = algorithm;
+
+       if (halbtc8723b1ant_is_common_action(btcoexist)) {
+       } else {
+               switch (coex_dm->cur_algorithm) {
+               case BT_8723B_1ANT_COEX_ALGO_SCO:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = SCO.\n");
+                       halbtc8723b1ant_action_sco(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_HID:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = HID.\n");
+                       halbtc8723b1ant_action_hid(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_A2DP:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = A2DP.\n");
+                       halbtc8723b1ant_action_a2dp(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = "
+                                 "A2DP+PAN(HS).\n");
+                       halbtc8723b1ant_action_a2dp_pan_hs(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_PANEDR:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = PAN(EDR).\n");
+                       halbtc8723b1ant_action_pan_edr(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_PANHS:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = HS mode.\n");
+                       halbtc8723b1ant_action_pan_hs(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = PAN+A2DP.\n");
+                       halbtc8723b1ant_action_pan_edr_a2dp(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_PANEDR_HID:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = "
+                                 "PAN(EDR)+HID.\n");
+                       halbtc8723b1ant_action_pan_edr_hid(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = "
+                                 "HID+A2DP+PAN.\n");
+                       halbtc8723b1ant_action_hid_a2dp_pan_edr(btcoexist);
+                       break;
+               case BT_8723B_1ANT_COEX_ALGO_HID_A2DP:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = HID+A2DP.\n");
+                       halbtc8723b1ant_action_hid_a2dp(btcoexist);
+                       break;
+               default:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action algorithm = "
+                                 "coexist All Off!!\n");
+                       break;
+               }
+               coex_dm->pre_algorithm = coex_dm->cur_algorithm;
+       }
+}
+
+void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+{
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+       bool wifi_connected = false, bt_hs_on = false;
+       bool limited_dig = false, bIncreaseScanDevNum = false;
+       bool b_bt_ctrl_agg_buf_size = false;
+       u8 agg_buf_size = 5;
+       u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
+
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                 "[BTCoex], RunCoexistMechanism()===>\n");
+
+       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;
+       }
+
+       if (coex_sta->under_ips) {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], wifi is under IPS !!!\n");
+               return;
+       }
+
+       if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
+           (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+           (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) {
+               limited_dig = true;
+               bIncreaseScanDevNum = true;
+       }
+
+       btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
+       btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM,
+                          &bIncreaseScanDevNum);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+                          &wifi_connected);
+
+       if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) {
+               halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+       } else {
+               if (wifi_connected) {
+                       wifi_rssi_state =
+                               halbtc8723b1ant_wifi_rssi_state(btcoexist,
+                                                               1, 2, 30, 0);
+                       if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                           (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                               halbtc8723b1ant_limited_tx(btcoexist,
+                                                          NORMAL_EXEC,
+                                                          1, 1, 1, 1);
+                       } else {
+                               halbtc8723b1ant_limited_tx(btcoexist,
+                                                          NORMAL_EXEC,
+                                                          1, 1, 1, 1);
+                       }
+               } else {
+                       halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC,
+                                                  0, 0, 0, 0);
+               }
+       }
+
+       if (bt_link_info->sco_exist) {
+               b_bt_ctrl_agg_buf_size = true;
+               agg_buf_size = 0x3;
+       } else if (bt_link_info->hid_exist) {
+               b_bt_ctrl_agg_buf_size = true;
+               agg_buf_size = 0x5;
+       } else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) {
+               b_bt_ctrl_agg_buf_size = true;
+               agg_buf_size = 0x8;
+       }
+       halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
+                                  b_bt_ctrl_agg_buf_size, agg_buf_size);
+
+       halbtc8723b1ant_run_sw_coexist_mechanism(btcoexist);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+       if (coex_sta->c2h_bt_inquiry_page) {
+               halbtc8723b1ant_action_bt_inquiry(btcoexist);
+               return;
+       } else if (bt_hs_on) {
+               halbtc8723b1ant_action_hs(btcoexist);
+               return;
+       }
+
+
+       if (!wifi_connected) {
+               bool 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)
+                       halbtc8723b1ant_action_wifi_not_connected_asso_auth_scan(btcoexist);
+               else
+                       halbtc8723b1ant_action_wifi_not_connected(btcoexist);
+       } else { /* wifi LPS/Busy */
+               halbtc8723b1ant_action_wifi_connected(btcoexist);
+       }
+}
+
+void halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+       /* force to reset coex mechanism */
+       halbtc8723b1ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6);
+       halbtc8723b1ant_dec_bt_pwr(btcoexist, FORCE_EXEC, false);
+
+       /* sw all off */
+       halbtc8723b1ant_sw_mechanism1(btcoexist, false, false, false, false);
+       halbtc8723b1ant_sw_mechanism2(btcoexist,false, false, false, 0x18);
+
+       halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+       halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+}
+
+void halbtc8723b1ant_init_hw_config(struct btc_coexist *btcoexist, bool backup)
+{
+       u32 u32tmp = 0;
+       u8 u8tmp = 0;
+       u32 cnt_bt_cal_chk = 0;
+
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                 "[BTCoex], 1Ant 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_retry_limit =
+                       btcoexist->btc_read_2byte(btcoexist, 0x42a);
+               coex_dm->backup_ampdu_max_time =
+                       btcoexist->btc_read_1byte(btcoexist, 0x456);
+       }
+
+       /* WiFi goto standby while GNT_BT 0-->1 */
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x780);
+       /* BT goto standby while GNT_BT 1-->0 */
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x2, 0xfffff, 0x500);
+
+       btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+       btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3);
+       btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77);
+
+
+       /* BT calibration check */
+       while (cnt_bt_cal_chk <= 20) {
+               u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x49d);
+               cnt_bt_cal_chk++;
+               if (u32tmp & BIT0) {
+                       BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                                 "[BTCoex], ########### BT "
+                                 "calibration(cnt=%d) ###########\n",
+                                 cnt_bt_cal_chk);
+                       mdelay(50);
+               } else {
+                       BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                                 "[BTCoex], ********** BT NOT "
+                                 "calibration (cnt=%d)**********\n",
+                                 cnt_bt_cal_chk);
+                       break;
+               }
+       }
+
+       /* 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 */
+       /*0x76e[3] =1, WLAN_Act control by PTA */
+       btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+       btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1);
+       btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
+
+       /*Antenna config */
+       halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_PTA, true, false);
+       /* PTA parameter */
+       halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+
+}
+
+void halbtc8723b1ant_wifi_off_hw_cfg(struct btc_coexist *btcoexist)
+{
+       /* set wlan_act to low */
+       btcoexist->btc_write_1byte(btcoexist, 0x76e, 0);
+}
+
+/**************************************************************
+ * work around function start with wa_halbtc8723b1ant_
+ **************************************************************/
+/**************************************************************
+ * extern function start with EXhalbtc8723b1ant_
+ **************************************************************/
+
+void ex_halbtc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist)
+{
+       halbtc8723b1ant_init_hw_config(btcoexist, true);
+}
+
+void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                 "[BTCoex], Coex Mechanism Init!!\n");
+
+       btcoexist->stop_coex_dm = false;
+
+       halbtc8723b1ant_init_coex_dm(btcoexist);
+
+       halbtc8723b1ant_query_bt_info(btcoexist);
+}
+
+void ex_halbtc8723b1ant_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;
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+       u8 *cli_buf = btcoexist->cli_buf;
+       u8 u8tmp[4], i, bt_info_ext, psTdmaCase=0;
+       u16 u16tmp[4];
+       u32 u32tmp[4];
+       bool roam = false, scan = false;
+       bool link = false, wifi_under_5g = false;
+       bool bt_hs_on = false, wifi_busy = false;
+       s32 wifi_rssi =0, bt_hs_rssi = 0;
+       u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck;
+       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 (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->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/ %d",
+                  "Ant PG Num/ Ant Mech/ Ant Pos:", \
+                  board_info->pg_ant_num, board_info->btdm_ant_num,
+                  board_info->btdm_ant_pos);
+       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_%x/ 0x%x/ 0x%x(%d)",
+                  "CoexVer/ FwVer/ PatchVer", \
+                  glcoex_ver_date_8723b_1ant, glcoex_ver_8723b_1ant,
+                  fw_ver, bt_patch_ver, bt_patch_ver);
+       CL_PRINTF(cli_buf);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+       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 / HsChnl(HsMode)", \
+                  wifi_dot11_chnl, wifi_hs_chnl, 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_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_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status)?
+                     "non-connected idle":
+                       ((BT_8723B_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);
+
+
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d",
+               "SCO/HID/PAN/A2DP", bt_link_info->sco_exist,
+               bt_link_info->hid_exist, bt_link_info->pan_exist,
+               bt_link_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_8723B_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)",
+                                  GLBtInfoSrc8723b1Ant[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.lps_1ant,
+                  btcoexist->bt_info.rpwm_1ant);
+       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 ",
+                          "SM1[ShRf/ LpRA/ LimDig]", \
+                          coex_dm->cur_rf_rx_lpf_shrink,
+                          coex_dm->cur_low_penalty_ra,
+                          btcoexist->bt_info.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_backoff,
+                          coex_dm->cur_dac_swing_on,
+                          coex_dm->cur_dac_swing_lvl);
+               CL_PRINTF(cli_buf);
+
+
+               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);
+
+               psTdmaCase = 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],
+                          psTdmaCase, coex_dm->auto_tdma_adjust);
+               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);
+       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_retry_limit,
+                  coex_dm->backup_ampdu_max_time);
+       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);
+
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc);
+       u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x880);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+                  "0x778/0x6cc/0x880[29:25]", u8tmp[0], u32tmp[0],
+                  (u32tmp[1] & 0x3e000000) >> 25);
+       CL_PRINTF(cli_buf);
+
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948);
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67);
+       u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+                  "0x948/ 0x67[5] / 0x765",
+                  u32tmp[0], ((u8tmp[0] & 0x20)>> 5), u8tmp[1]);
+       CL_PRINTF(cli_buf);
+
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c);
+       u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930);
+       u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+                  "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]",
+                  u32tmp[0] & 0x3, u32tmp[1] & 0xff, u32tmp[2] & 0x3);
+       CL_PRINTF(cli_buf);
+
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39);
+       u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+       u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+                  "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+                  "0x38[11]/0x40/0x4c[24:23]/0x64[0]",
+                  ((u8tmp[0] & 0x8)>>3), u8tmp[1],
+                  ((u32tmp[0] & 0x01800000) >> 23), u8tmp[2] & 0x1);
+       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);
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+                  "0xc50(dig)/0x49c(null-drop)", u32tmp[0] & 0xff, u8tmp[0]);
+       CL_PRINTF(cli_buf);
+
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0);
+       u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4);
+       u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8);
+       u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0);
+
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b);
+       u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
+
+       fa_ofdm = ((u32tmp[0] & 0xffff0000) >> 16) +
+                 ((u32tmp[1] & 0xffff0000) >> 16) +
+                  (u32tmp[1] & 0xffff) +
+                  (u32tmp[2] & 0xffff) + \
+                 ((u32tmp[3] & 0xffff0000) >> 16) +
+                  (u32tmp[3] & 0xffff) ;
+       fa_cck = (u8tmp[0] << 8) + u8tmp[1];
+
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+                  "OFDM-CCA/OFDM-FA/CCK-FA",
+                  u32tmp[0] & 0xffff, fa_ofdm, fa_cck);
+       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);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+                  "0x6c0/0x6c4/0x6c8(coexTable)",
+                  u32tmp[0], u32tmp[1], u32tmp[2]);
+       CL_PRINTF(cli_buf);
+
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+                  "0x770(high-pri rx/tx)", 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(low-pri rx/tx)", coex_sta->low_priority_rx,
+                  coex_sta->low_priority_tx);
+       CL_PRINTF(cli_buf);
+#if(BT_AUTO_REPORT_ONLY_8723B_1ANT == 1)
+       halbtc8723b1ant_monitor_bt_ctr(btcoexist);
+#endif
+       btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
+}
+
+
+void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
+{
+
+       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;
+
+               halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT,
+                                          false, true);
+                /* set PTA control */
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+               halbtc8723b1ant_coex_table_with_type(btcoexist,
+                       NORMAL_EXEC, 0);
+       } else if (BTC_IPS_LEAVE == type) {
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                         "[BTCoex], IPS LEAVE notify\n");
+               coex_sta->under_ips = false;
+
+               halbtc8723b1ant_run_coexist_mechanism(btcoexist);
+       }
+}
+
+void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 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_LPS_DISABLE == type) {
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                         "[BTCoex], LPS DISABLE notify\n");
+               coex_sta->under_lps = false;
+       }
+}
+
+void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
+{
+       bool wifi_connected = false, bt_hs_on = false;
+
+       if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
+           btcoexist->bt_info.bt_disabled)
+               return;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+                          &wifi_connected);
+
+       halbtc8723b1ant_query_bt_info(btcoexist);
+
+       if (coex_sta->c2h_bt_inquiry_page) {
+               halbtc8723b1ant_action_bt_inquiry(btcoexist);
+               return;
+       } else if (bt_hs_on) {
+               halbtc8723b1ant_action_hs(btcoexist);
+               return;
+       }
+
+       if (BTC_SCAN_START == type) {
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                         "[BTCoex], SCAN START notify\n");
+               if (!wifi_connected)    /* non-connected scan */
+                       halbtc8723b1ant_action_wifi_not_connected_asso_auth_scan(btcoexist);
+               else    /* wifi is connected */
+                       halbtc8723b1ant_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 */
+                       halbtc8723b1ant_action_wifi_not_connected(btcoexist);
+               else
+                       halbtc8723b1ant_action_wifi_connected(btcoexist);
+       }
+}
+
+void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
+{
+       bool wifi_connected = false, bt_hs_on = false;
+
+       if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
+           btcoexist->bt_info.bt_disabled)
+               return;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+       if (coex_sta->c2h_bt_inquiry_page) {
+               halbtc8723b1ant_action_bt_inquiry(btcoexist);
+               return;
+       } else if (bt_hs_on) {
+               halbtc8723b1ant_action_hs(btcoexist);
+               return;
+       }
+
+       if (BTC_ASSOCIATE_START == type) {
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                         "[BTCoex], CONNECT START notify\n");
+               halbtc8723b1ant_action_wifi_not_connected_asso_auth_scan(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 */
+                       halbtc8723b1ant_action_wifi_not_connected(btcoexist);
+               else
+                       halbtc8723b1ant_action_wifi_connected(btcoexist);
+       }
+}
+
+void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist,
+                                           u8 type)
+{
+       u8 h2c_parameter[3] ={0};
+       u32 wifi_bw;
+       u8 wifiCentralChnl;
+
+       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,
+                          &wifiCentralChnl);
+
+       if ((BTC_MEDIA_CONNECT == type) &&
+           (wifiCentralChnl <= 14)) {
+               h2c_parameter[0] = 0x0;
+               h2c_parameter[1] = wifiCentralChnl;
+               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_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist,
+                                             u8 type)
+{
+       bool bt_hs_on = false;
+
+       if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
+           btcoexist->bt_info.bt_disabled)
+               return;
+
+       coex_sta->special_pkt_period_cnt = 0;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+       if (coex_sta->c2h_bt_inquiry_page) {
+               halbtc8723b1ant_action_bt_inquiry(btcoexist);
+               return;
+       } else if (bt_hs_on) {
+               halbtc8723b1ant_action_hs(btcoexist);
+               return;
+       }
+
+       if (BTC_PACKET_DHCP == type ||
+               BTC_PACKET_EAPOL == type) {
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                         "[BTCoex], special Packet(%d) notify\n", type);
+               halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist);
+       }
+}
+
+void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
+                                      u8 *tmp_buf, u8 length)
+{
+       u8 bt_info = 0;
+       u8 i, rsp_source = 0;
+       bool wifi_connected = false;
+       bool bt_busy = false;
+
+       coex_sta->c2h_bt_info_req_sent = false;
+
+       rsp_source = tmp_buf[0] & 0xf;
+       if (rsp_source >= BT_INFO_SRC_8723B_1ANT_MAX)
+               rsp_source = BT_INFO_SRC_8723B_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%02x]\n", tmp_buf[i]);
+               else
+                       BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                                 "0x%02x, ", tmp_buf[i]);
+       }
+
+       if (BT_INFO_SRC_8723B_1ANT_WIFI_FW != rsp_source) {
+               coex_sta->bt_retry_cnt =        /* [3:0] */
+                       coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
+
+               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)
+               {
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], BT ext info bit1 check, "
+                                 "send wifi BW&Chnl to BT!!\n");
+                       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+                                          &wifi_connected);
+                       if(wifi_connected)
+                               ex_halbtc8723b1ant_media_status_notify(btcoexist,
+                                                            BTC_MEDIA_CONNECT);
+                       else
+                               ex_halbtc8723b1ant_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,
+                                         "[BTCoex], BT ext info bit3 check, "
+                                         "set BT NOT ignore Wlan active!!\n");
+                               halbtc8723b1ant_ignore_wlan_act(btcoexist,
+                                                               FORCE_EXEC,
+                                                               false);
+                       }
+               } else {
+                       /* BT already NOT ignore Wlan active, do nothing here.*/
+               }
+#if(BT_AUTO_REPORT_ONLY_8723B_1ANT == 0)
+               if (coex_sta->bt_info_ext & BIT4) {
+                       /* BT auto report already enabled, do nothing */
+               } else {
+                       halbtc8723b1ant_bt_auto_report(btcoexist, FORCE_EXEC,
+                                                      true);
+               }
+#endif
+       }
+
+       /* check BIT2 first ==> check if bt is under inquiry or page scan */
+       if (bt_info & BT_INFO_8723B_1ANT_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_8723B_1ANT_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_8723B_1ANT_B_FTP)
+                       coex_sta->pan_exist = true;
+               else
+                       coex_sta->pan_exist = false;
+               if (bt_info & BT_INFO_8723B_1ANT_B_A2DP)
+                       coex_sta->a2dp_exist = true;
+               else
+                       coex_sta->a2dp_exist = false;
+               if (bt_info & BT_INFO_8723B_1ANT_B_HID)
+                       coex_sta->hid_exist = true;
+               else
+                       coex_sta->hid_exist = false;
+               if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO)
+                       coex_sta->sco_exist = true;
+               else
+                       coex_sta->sco_exist = false;
+       }
+
+       halbtc8723b1ant_update_bt_link_info(btcoexist);
+
+       if (!(bt_info&BT_INFO_8723B_1ANT_B_CONNECTION)) {
+               coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), "
+                         "BT Non-Connected idle!!!\n");
+       /* connection exists but no busy */
+       } else if (bt_info == BT_INFO_8723B_1ANT_B_CONNECTION) {
+               coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
+       } else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) ||
+               (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY)) {
+               coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_SCO_BUSY;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), "
+                         "BT SCO busy!!!\n");
+       } else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) {
+               if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status)
+                       coex_dm->auto_tdma_adjust = false;
+
+               coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_ACL_BUSY;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
+       } else {
+               coex_dm->bt_status =
+                       BT_8723B_1ANT_BT_STATUS_MAX;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), BT Non-Defined state!!\n");
+       }
+
+       if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
+           (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+           (BT_8723B_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);
+
+       halbtc8723b1ant_run_coexist_mechanism(btcoexist);
+}
+
+void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist)
+{
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n");
+
+       btcoexist->stop_coex_dm = true;
+
+       halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT, false, true);
+
+       halbtc8723b1ant_wifi_off_hw_cfg(btcoexist);
+       halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
+
+       halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+                                        0x0, 0x0);
+       halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
+
+       ex_halbtc8723b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
+}
+
+void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
+{
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Pnp notify\n");
+
+       if (BTC_WIFI_PNP_SLEEP == pnp_state) {
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                         "[BTCoex], Pnp notify to SLEEP\n");
+               btcoexist->stop_coex_dm = true;
+               halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
+               halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+                                                0x0, 0x0);
+               halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 9);
+       } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) {
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+                         "[BTCoex], Pnp notify to WAKE UP\n");
+               btcoexist->stop_coex_dm = false;
+               halbtc8723b1ant_init_hw_config(btcoexist, false);
+               halbtc8723b1ant_init_coex_dm(btcoexist);
+               halbtc8723b1ant_query_bt_info(btcoexist);
+       }
+}
+
+void ex_halbtc8723b1ant_periodical(struct btc_coexist *btcoexist)
+{
+       struct btc_board_info *board_info = &btcoexist->board_info;
+       struct btc_stack_info *stack_info = &btcoexist->stack_info;
+       static u8 dis_ver_info_cnt = 0;
+       u32 fw_ver = 0, bt_patch_ver = 0;
+
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                 "[BTCoex], =========================="
+                 "Periodical===========================\n");
+
+       if (dis_ver_info_cnt <= 5) {
+               dis_ver_info_cnt += 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", \
+                         board_info->pg_ant_num, board_info->btdm_ant_num,
+                         board_info->btdm_ant_pos);
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                         "[BTCoex], 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,
+                         "[BTCoex], CoexVer/ FwVer/ PatchVer "
+                         "= %d_%x/ 0x%x/ 0x%x(%d)\n", \
+                         glcoex_ver_date_8723b_1ant,
+                         glcoex_ver_8723b_1ant, fw_ver,
+                         bt_patch_ver, bt_patch_ver);
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                         "[BTCoex], *****************************"
+                         "***********************************\n");
+       }
+
+#if(BT_AUTO_REPORT_ONLY_8723B_1ANT == 0)
+       halbtc8723b1ant_query_bt_info(btcoexist);
+       halbtc8723b1ant_monitor_bt_ctr(btcoexist);
+       halbtc8723b1ant_monitor_bt_enable_disable(btcoexist);
+#else
+       if (halbtc8723b1ant_is_wifi_status_changed(btcoexist) ||
+           coex_dm->auto_tdma_adjust) {
+               if (coex_sta->special_pkt_period_cnt > 2)
+                       halbtc8723b1ant_run_coexist_mechanism(btcoexist);
+       }
+
+       coex_sta->special_pkt_period_cnt++;
+#endif
+}
+
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8723b1ant.h b/drivers/staging/rtl8821ae/btcoexist/halbtc8723b1ant.h
new file mode 100644 (file)
index 0000000..5ce292f
--- /dev/null
@@ -0,0 +1,175 @@
+/**********************************************************************
+ * The following is for 8723B 1ANT BT Co-exist definition
+ **********************************************************************/
+#define        BT_AUTO_REPORT_ONLY_8723B_1ANT                  1
+
+#define        BT_INFO_8723B_1ANT_B_FTP                        BIT7
+#define        BT_INFO_8723B_1ANT_B_A2DP                       BIT6
+#define        BT_INFO_8723B_1ANT_B_HID                        BIT5
+#define        BT_INFO_8723B_1ANT_B_SCO_BUSY                   BIT4
+#define        BT_INFO_8723B_1ANT_B_ACL_BUSY                   BIT3
+#define        BT_INFO_8723B_1ANT_B_INQ_PAGE                   BIT2
+#define        BT_INFO_8723B_1ANT_B_SCO_ESCO                   BIT1
+#define        BT_INFO_8723B_1ANT_B_CONNECTION                 BIT0
+
+#define        BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_)       \
+               (((_BT_INFO_EXT_&BIT0))? true:false)
+
+#define        BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT             2
+
+typedef enum _BT_INFO_SRC_8723B_1ANT{
+       BT_INFO_SRC_8723B_1ANT_WIFI_FW                  = 0x0,
+       BT_INFO_SRC_8723B_1ANT_BT_RSP                   = 0x1,
+       BT_INFO_SRC_8723B_1ANT_BT_ACTIVE_SEND           = 0x2,
+       BT_INFO_SRC_8723B_1ANT_MAX
+}BT_INFO_SRC_8723B_1ANT,*PBT_INFO_SRC_8723B_1ANT;
+
+typedef enum _BT_8723B_1ANT_BT_STATUS{
+       BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE      = 0x0,
+       BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE          = 0x1,
+       BT_8723B_1ANT_BT_STATUS_INQ_PAGE                = 0x2,
+       BT_8723B_1ANT_BT_STATUS_ACL_BUSY                = 0x3,
+       BT_8723B_1ANT_BT_STATUS_SCO_BUSY                = 0x4,
+       BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY            = 0x5,
+       BT_8723B_1ANT_BT_STATUS_MAX
+}BT_8723B_1ANT_BT_STATUS,*PBT_8723B_1ANT_BT_STATUS;
+
+typedef enum _BT_8723B_1ANT_WIFI_STATUS{
+       BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE                    = 0x0,
+       BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN          = 0x1,
+       BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN                        = 0x2,
+       BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT                 = 0x3,
+       BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE                        = 0x4,
+       BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY                        = 0x5,
+       BT_8723B_1ANT_WIFI_STATUS_MAX
+}BT_8723B_1ANT_WIFI_STATUS,*PBT_8723B_1ANT_WIFI_STATUS;
+
+typedef enum _BT_8723B_1ANT_COEX_ALGO{
+       BT_8723B_1ANT_COEX_ALGO_UNDEFINED               = 0x0,
+       BT_8723B_1ANT_COEX_ALGO_SCO                     = 0x1,
+       BT_8723B_1ANT_COEX_ALGO_HID                     = 0x2,
+       BT_8723B_1ANT_COEX_ALGO_A2DP                    = 0x3,
+       BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS              = 0x4,
+       BT_8723B_1ANT_COEX_ALGO_PANEDR                  = 0x5,
+       BT_8723B_1ANT_COEX_ALGO_PANHS                   = 0x6,
+       BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP             = 0x7,
+       BT_8723B_1ANT_COEX_ALGO_PANEDR_HID              = 0x8,
+       BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR         = 0x9,
+       BT_8723B_1ANT_COEX_ALGO_HID_A2DP                = 0xa,
+       BT_8723B_1ANT_COEX_ALGO_MAX                     = 0xb,
+}BT_8723B_1ANT_COEX_ALGO,*PBT_8723B_1ANT_COEX_ALGO;
+
+struct coex_dm_8723b_1ant{
+       /* fw mechanism */
+       bool pre_dec_bt_pwr;
+       bool 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 auto_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_backoff;
+       bool cur_adc_backoff;
+       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_retry_limit;
+       u8 backup_ampdu_max_time;
+
+       /* algorithm related */
+       u8 pre_algorithm;
+       u8 cur_algorithm;
+       u8 bt_status;
+       u8 wifi_chnl_info[3];
+
+       u32 prera_mask;
+       u32 curra_mask;
+       u8 pre_arfr_type;
+       u8 cur_arfr_type;
+       u8 pre_retry_limit_type;
+       u8 cur_retry_limit_type;
+       u8 pre_ampdu_time_type;
+       u8 cur_ampdu_time_type;
+
+       u8 error_condition;
+};
+
+struct coex_sta_8723b_1ant{
+       bool bt_link_exist;
+       bool sco_exist;
+       bool a2dp_exist;
+       bool hid_exist;
+       bool pan_exist;
+
+       bool under_lps;
+       bool under_ips;
+       u32 special_pkt_period_cnt;
+       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_8723B_1ANT_MAX][10];
+       u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_1ANT_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_halbtc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist);
+void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist);
+void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist,
+                                           u8 type);
+void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist,
+                                             u8 type);
+void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
+                                      u8 *tmpbuf, u8 length);
+void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist);
+void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpState);
+void ex_halbtc8723b1ant_periodical(struct btc_coexist *btcoexist);
+void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist);
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8723b2ant.c b/drivers/staging/rtl8821ae/btcoexist/halbtc8723b2ant.c
new file mode 100644 (file)
index 0000000..83b1b42
--- /dev/null
@@ -0,0 +1,4185 @@
+/***************************************************************
+ * Description:
+ *
+ * This file is for RTL8723B 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_8723b_2ant glcoex_dm_8723b_2ant;
+static struct coex_dm_8723b_2ant *coex_dm = &glcoex_dm_8723b_2ant;
+static struct coex_sta_8723b_2ant glcoex_sta_8723b_2ant;
+static struct coex_sta_8723b_2ant *coex_sta = &glcoex_sta_8723b_2ant;
+
+const char *const glbt_info_src_8723b_2ant[] = {
+       "BT Info[wifi fw]",
+       "BT Info[bt rsp]",
+       "BT Info[bt auto report]",
+};
+
+u32 glcoex_ver_date_8723b_2ant = 20131113;
+u32 glcoex_ver_8723b_2ant = 0x3f;
+
+/**************************************************************
+ * local function proto type if needed
+ **************************************************************/
+/**************************************************************
+ * local function start with halbtc8723b2ant_
+ **************************************************************/
+u8 halbtc8723b2ant_bt_rssi_state(u8 level_num, u8 rssi_thresh, u8 rssi_thresh1)
+{
+       s32 bt_rssi = 0;
+       u8 bt_rssi_state = coex_sta->pre_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_8723B_2ANT) {
+                               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_8723B_2ANT) {
+                               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_8723B_2ANT) {
+                               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;
+}
+
+u8 halbtc8723b2ant_wifi_rssi_state(struct btc_coexist *btcoexist,
+                                  u8 index, u8 level_num,
+                                  u8 rssi_thresh, u8 rssi_thresh1)
+{
+       s32 wifi_rssi=0;
+       u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];
+
+       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_8723B_2ANT) {
+                               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_8723B_2ANT) {
+                               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_8723B_2ANT) {
+                               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 halbtc8723b2ant_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 = true;
+
+       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;
+               if (!bt_disabled) {
+               } else {
+               }
+       }
+}
+
+void halbtc8723b2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
+{
+       u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
+       u32 reg_hp_tx = 0, reg_hp_rx = 0;
+       u32 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 halbtc8723b2ant_query_bt_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 halbtc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
+{
+       static bool pre_wifi_busy = false;
+       static bool pre_under_4way = false;
+       static bool pre_bt_hs_on = false;
+       bool wifi_busy = false, under_4way = false, bt_hs_on = 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_hs_on);
+       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_hs_on != pre_bt_hs_on) {
+                       pre_bt_hs_on = bt_hs_on;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+void halbtc8723b2ant_update_bt_link_info(struct btc_coexist *btcoexist)
+{
+       /*struct btc_stack_info *stack_info = &btcoexist->stack_info;*/
+       struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+       bool bt_hs_on = false;
+
+#if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) /* profile from bt patch */
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+       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_hs_on) {
+               bt_link_info->pan_exist = true;
+               bt_link_info->bt_link_exist = true;
+       }
+#else  /* profile from bt stack */
+       bt_link_info->bt_link_exist = stack_info->bt_link_exist;
+       bt_link_info->sco_exist = stack_info->sco_exist;
+       bt_link_info->a2dp_exist = stack_info->a2dp_exist;
+       bt_link_info->pan_exist = stack_info->pan_exist;
+       bt_link_info->hid_exist = stack_info->hid_exist;
+
+       /*for win-8 stack HID report error*/
+       if (!stack_info->hid_exist)
+               stack_info->hid_exist = coex_sta->hid_exist;
+       /*sync  BTInfo with BT firmware and stack*/
+       /* when stack HID report error, here we use the info from bt fw.*/
+       if (!stack_info->bt_link_exist)
+               stack_info->bt_link_exist = coex_sta->bt_link_exist;
+#endif
+       /* 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 halbtc8723b2ant_action_algorithm(struct btc_coexist *btcoexist)
+{
+       struct btc_bt_link_info *bt_link_info=&btcoexist->bt_link_info;
+       bool bt_hs_on = false;
+       u8 algorithm = BT_8723B_2ANT_COEX_ALGO_UNDEFINED;
+       u8 num_of_diff_profile = 0;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+       if (!bt_link_info->bt_link_exist) {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], No BT link exists!!!\n");
+               return algorithm;
+       }
+
+       if (bt_link_info->sco_exist)
+               num_of_diff_profile++;
+       if (bt_link_info->hid_exist)
+               num_of_diff_profile++;
+       if (bt_link_info->pan_exist)
+               num_of_diff_profile++;
+       if (bt_link_info->a2dp_exist)
+               num_of_diff_profile++;
+
+       if (num_of_diff_profile == 1) {
+               if (bt_link_info->sco_exist) {
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], SCO only\n");
+                       algorithm = BT_8723B_2ANT_COEX_ALGO_SCO;
+               } else {
+                       if (bt_link_info->hid_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], HID only\n");
+                               algorithm = BT_8723B_2ANT_COEX_ALGO_HID;
+                       } else if (bt_link_info->a2dp_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], A2DP only\n");
+                               algorithm = BT_8723B_2ANT_COEX_ALGO_A2DP;
+                       } else if (bt_link_info->pan_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], PAN(HS) only\n");
+                                       algorithm =
+                                               BT_8723B_2ANT_COEX_ALGO_PANHS;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], PAN(EDR) only\n");
+                                       algorithm =
+                                               BT_8723B_2ANT_COEX_ALGO_PANEDR;
+                               }
+                       }
+               }
+       } else if (num_of_diff_profile == 2) {
+               if (bt_link_info->sco_exist) {
+                       if (bt_link_info->hid_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], SCO + HID\n");
+                               algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                       } else if (bt_link_info->a2dp_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], SCO + A2DP ==> SCO\n");
+                               algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                       } else if (bt_link_info->pan_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], SCO + PAN(HS)\n");
+                                       algorithm = BT_8723B_2ANT_COEX_ALGO_SCO;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], SCO + PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       }
+               } else {
+                       if (bt_link_info->hid_exist &&
+                           bt_link_info->a2dp_exist) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], HID + A2DP\n");
+                               algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP;
+                       } else if (bt_link_info->hid_exist &&
+                                  bt_link_info->pan_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], HID + PAN(HS)\n");
+                                       algorithm = BT_8723B_2ANT_COEX_ALGO_HID;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], HID + PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       } else if (bt_link_info->pan_exist &&
+                                  bt_link_info->a2dp_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], A2DP + PAN(HS)\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex],A2DP + PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP;
+                               }
+                       }
+               }
+       } else if (num_of_diff_profile == 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,
+                                         "[BTCoex], SCO + HID + A2DP"
+                                         " ==> HID\n");
+                               algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                       } else if (bt_link_info->hid_exist &&
+                                  bt_link_info->pan_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], SCO + HID + "
+                                                 "PAN(HS)\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], SCO + HID + "
+                                                 "PAN(EDR)\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       } else if (bt_link_info->pan_exist &&
+                                  bt_link_info->a2dp_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], SCO + A2DP + "
+                                                 "PAN(HS)\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], SCO + A2DP + "
+                                                 "PAN(EDR) ==> HID\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       }
+               } else {
+                       if (bt_link_info->hid_exist &&
+                           bt_link_info->pan_exist &&
+                           bt_link_info->a2dp_exist) {
+                               if (bt_hs_on) {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], HID + A2DP + "
+                                                 "PAN(HS)\n");
+                                       algorithm =
+                                           BT_8723B_2ANT_COEX_ALGO_HID_A2DP;
+                               } else {
+                                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                                 "[BTCoex], HID + A2DP + "
+                                                 "PAN(EDR)\n");
+                                       algorithm =
+                                       BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
+                               }
+                       }
+               }
+       } else if (num_of_diff_profile >= 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_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_8723B_2ANT_COEX_ALGO_PANEDR_HID;
+                               }
+                       }
+               }
+       }
+
+       return algorithm;
+}
+
+bool halbtc8723b2ant_need_to_dec_bt_pwr(struct btc_coexist *btcoexist)
+{
+       bool bRet = false;
+       bool bt_hs_on = false, wifi_connected = false;
+       s32 bt_hs_rssi=0;
+       u8 bt_rssi_state;
+
+       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;
+
+       bt_rssi_state = halbtc8723b2ant_bt_rssi_state(2, 29, 0);
+
+       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");
+                               bRet = true;
+                       }
+               } else {
+                       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
+                                         "[BTCoex], Need to decrease bt "
+                                         "power for Wifi is connected!!\n");
+                               bRet = true;
+                       }
+               }
+       }
+
+       return bRet;
+}
+
+void halbtc8723b2ant_set_fw_dac_swing_level(struct btc_coexist *btcoexist,
+                                           u8 dac_swing_lvl)
+{
+       u8 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 halbtc8723b2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist,
+                                      bool dec_bt_pwr)
+{
+       u8 h2c_parameter[1] = {0};
+
+       h2c_parameter[0] = 0;
+
+       if (dec_bt_pwr)
+               h2c_parameter[0] |= BIT1;
+
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+                 "[BTCoex], decrease Bt Power : %s, FW write 0x62=0x%x\n",
+                 (dec_bt_pwr? "Yes!!":"No!!"), h2c_parameter[0]);
+
+       btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
+}
+
+void halbtc8723b2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
+                               bool force_exec, bool dec_bt_pwr)
+{
+       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], bPreDecBtPwr=%d, bCurDecBtPwr=%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;
+       }
+       halbtc8723b2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr);
+
+       coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr;
+}
+
+void halbtc8723b2ant_set_bt_auto_report(struct btc_coexist *btcoexist,
+                                       bool enable_auto_report)
+{
+       u8 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);
+}
+
+void halbtc8723b2ant_bt_auto_report(struct btc_coexist *btcoexist,
+                                   bool force_exec, bool 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], 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;
+       }
+       halbtc8723b2ant_set_bt_auto_report(btcoexist,
+                                          coex_dm->cur_bt_auto_report);
+
+       coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
+}
+
+void halbtc8723b2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist,
+                                     bool force_exec, u8 fw_dac_swing_lvl)
+{
+       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], 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;
+       }
+
+       halbtc8723b2ant_set_fw_dac_swing_level(btcoexist,
+                                              coex_dm->cur_fw_dac_swing_lvl);
+       coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
+}
+
+void halbtc8723b2ant_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 halbtc8723b2ant_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;
+       }
+       halbtc8723b2ant_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 halbtc8723b2ant_set_sw_penalty_txrate_adaptive(
+                                               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 halbtc8723b2ant_low_penalty_ra(struct btc_coexist *btcoexist,
+                                   bool force_exec, bool 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], 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;
+       }
+       halbtc8723b2ant_set_sw_penalty_txrate_adaptive(btcoexist,
+                                               coex_dm->cur_low_penalty_ra);
+
+       coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
+}
+
+void halbtc8723b2ant_set_dac_swing_reg(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 halbtc8723b2ant_set_sw_fulltime_dac_swing(struct btc_coexist *btcoexist,
+                                              bool sw_dac_swing_on,
+                                              u32 sw_dac_swing_lvl)
+{
+       if(sw_dac_swing_on)
+               halbtc8723b2ant_set_dac_swing_reg(btcoexist, sw_dac_swing_lvl);
+       else
+               halbtc8723b2ant_set_dac_swing_reg(btcoexist, 0x18);
+}
+
+
+void halbtc8723b2ant_dac_swing(struct btc_coexist *btcoexist,
+                              bool force_exec, bool dac_swing_on,
+                              u32 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], bPreDacSwingOn=%d, preDacSwingLvl=0x%x,"
+                         " bCurDacSwingOn=%d, curDacSwingLvl=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;
+       }
+       mdelay(30);
+       halbtc8723b2ant_set_sw_fulltime_dac_swing(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 halbtc8723b2ant_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 halbtc8723b2ant_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;
+       }
+       halbtc8723b2ant_set_adc_backoff(btcoexist, coex_dm->cur_adc_back_off);
+
+       coex_dm->pre_adc_back_off = coex_dm->cur_adc_back_off;
+}
+
+void halbtc8723b2ant_set_agc_table(struct btc_coexist *btcoexist,
+                                  bool agc_table_en)
+{
+       u8 rssi_adjust_val = 0;
+
+       /*  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, 0x6e1A0001);
+               btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6d1B0001);
+               btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6c1C0001);
+               btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6b1D0001);
+               btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6a1E0001);
+               btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x691F0001);
+               btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x68200001);
+       } 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);
+               btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa4200001);
+       }
+
+
+       /* RF Gain */
+       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, 0x38fff);
+               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b,
+                                         0xfffff, 0x38ffe);
+       } 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, 0x380c3);
+               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b,
+                                         0xfffff, 0x28ce6);
+       }
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xed, 0xfffff, 0x1);
+
+       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, 0x40,
+                                         0xfffff, 0x38fff);
+               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40,
+                                         0xfffff, 0x38ffe);
+       } else {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+                         "[BTCoex], Agc Table Off!\n");
+               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40,
+                                         0xfffff, 0x380c3);
+               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40,
+                                         0xfffff, 0x28ce6);
+       }
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xed, 0xfffff, 0x0);
+
+       /* set rssiAdjustVal for wifi module. */
+       if (agc_table_en)
+               rssi_adjust_val = 8;
+       btcoexist->btc_set(btcoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON,
+                          &rssi_adjust_val);
+}
+
+void halbtc8723b2ant_agc_table(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;
+       }
+       halbtc8723b2ant_set_agc_table(btcoexist, agc_table_en);
+
+       coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en;
+}
+
+void halbtc8723b2ant_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 halbtc8723b2ant_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,"
+                 " 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], preVal0x6c0=0x%x, "
+                         "preVal0x6c4=0x%x, preVal0x6c8=0x%x, "
+                         "preVal0x6cc=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], curVal0x6c0=0x%x, "
+                         "curVal0x6c4=0x%x, curVal0x6c8=0x%x, "
+                         "curVal0x6cc=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;
+       }
+       halbtc8723b2ant_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 halbtc8723b2ant_coex_table_with_type(struct btc_coexist *btcoexist,
+                                         bool force_exec, u8 type)
+{
+       switch (type) {
+       case 0:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555,
+                                          0x55555555, 0xffff, 0x3);
+               break;
+       case 1:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555,
+                                          0x5afa5afa, 0xffff, 0x3);
+               break;
+       case 2:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
+                                          0x5a5a5a5a, 0xffff, 0x3);
+               break;
+       case 3:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa,
+                                          0xaaaaaaaa, 0xffff, 0x3);
+               break;
+       case 4:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0xffffffff,
+                                          0xffffffff, 0xffff, 0x3);
+               break;
+       case 5:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x5fff5fff,
+                                          0x5fff5fff, 0xffff, 0x3);
+               break;
+       case 6:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
+                                          0x5a5a5a5a, 0xffff, 0x3);
+               break;
+       case 7:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
+                                          0x5afa5afa, 0xffff, 0x3);
+               break;
+       case 8:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x5aea5aea,
+                                          0x5aea5aea, 0xffff, 0x3);
+               break;
+       case 9:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
+                                          0x5aea5aea, 0xffff, 0x3);
+               break;
+       case 10:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
+                                          0x5aff5aff, 0xffff, 0x3);
+               break;
+       case 11:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
+                                          0x5a5f5a5f, 0xffff, 0x3);
+               break;
+       case 12:
+               halbtc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
+                                          0x5f5f5f5f, 0xffff, 0x3);
+               break;
+       default:
+               break;
+       }
+}
+
+void halbtc8723b2ant_set_fw_ignore_wlan_act(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 halbtc8723b2ant_ignore_wlan_act(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, "
+                         "bCurIgnoreWlanAct = %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;
+       }
+       halbtc8723b2ant_set_fw_ignore_wlan_act(btcoexist, enable);
+
+       coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
+}
+
+void halbtc8723b2ant_set_fw_ps_tdma(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 halbtc8723b2ant_sw_mechanism1(struct btc_coexist *btcoexist,
+                                  bool shrink_rx_lpf, bool low_penalty_ra,
+                                  bool limited_dig, bool bt_lna_constrain)
+{
+       /*
+       u32     wifi_bw;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+       if(BTC_WIFI_BW_HT40 != wifi_bw)  //only shrink RF Rx LPF for HT40
+       {
+               if (shrink_rx_lpf)
+                       shrink_rx_lpf = false;
+       }
+       */
+
+       halbtc8723b2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf);
+       halbtc8723b2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
+}
+
+void halbtc8723b2ant_sw_mechanism2(struct btc_coexist *btcoexist,
+                                  bool agc_table_shift, bool adc_backoff,
+                                  bool sw_dac_swing, u32 dac_swing_lvl)
+{
+       halbtc8723b2ant_agc_table(btcoexist, NORMAL_EXEC, agc_table_shift);
+       /*halbtc8723b2ant_adc_backoff(btcoexist, NORMAL_EXEC, adc_backoff);*/
+       halbtc8723b2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing,
+                                 dac_swing_lvl);
+}
+
+void halbtc8723b2ant_set_ant_path(struct btc_coexist *btcoexist,
+                                 u8 antpos_type, bool init_hwcfg,
+                                 bool wifi_off)
+{
+       struct btc_board_info *board_info = &btcoexist->board_info;
+       u32 fw_ver = 0, u32tmp=0;
+       bool pg_ext_switch = false;
+       bool use_ext_switch = false;
+       u8 h2c_parameter[2] ={0};
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch);
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
+
+       if ((fw_ver<0xc0000) || pg_ext_switch)
+               use_ext_switch = true;
+
+       if (init_hwcfg) {
+               /* 0x4c[23]=0, 0x4c[24]=1  Antenna control by WL/BT */
+               u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+               u32tmp &= ~BIT23;
+               u32tmp |= BIT24;
+               btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
+
+               btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+               btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3);
+               btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77);
+               btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1);
+
+               /* Force GNT_BT to low */
+               btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
+               btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
+
+               if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
+                       /* tell firmware "no antenna inverse" */
+                       h2c_parameter[0] = 0;
+                       h2c_parameter[1] = 1;  /* ext switch type */
+                       btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
+                                               h2c_parameter);
+               } else {
+                       /* tell firmware "antenna inverse" */
+                       h2c_parameter[0] = 1;
+                       h2c_parameter[1] = 1;  /* ext switch type */
+                       btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
+                                               h2c_parameter);
+               }
+       }
+
+       /* ext switch setting */
+       if (use_ext_switch) {
+                /* fixed internal switch S1->WiFi, S0->BT */
+               btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
+               switch (antpos_type) {
+               case BTC_ANT_WIFI_AT_MAIN:
+                       /* ext switch main at wifi */
+                       btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
+                                                          0x3, 0x1);
+                       break;
+               case BTC_ANT_WIFI_AT_AUX:
+                       /* ext switch aux at wifi */
+                       btcoexist->btc_write_1byte_bitmask(btcoexist,
+                                                          0x92c, 0x3, 0x2);
+                       break;
+               }
+       } else {        /* internal switch */
+               /* fixed ext switch */
+               btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, 0x3, 0x1);
+               switch (antpos_type) {
+               case BTC_ANT_WIFI_AT_MAIN:
+                       /* fixed internal switch S1->WiFi, S0->BT */
+                       btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
+                       break;
+               case BTC_ANT_WIFI_AT_AUX:
+                       /* fixed internal switch S0->WiFi, S1->BT */
+                       btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
+                       break;
+               }
+       }
+}
+
+
+void halbtc8723b2ant_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:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
+                                                      0x1a, 0xe1, 0x90);
+                       break;
+               case 2:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
+                                                      0x12, 0xe1, 0x90);
+                       break;
+               case 3:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
+                                                      0x3, 0xf1, 0x90);
+                       break;
+               case 4:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10,
+                                                      0x03, 0xf1, 0x90);
+                       break;
+               case 5:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
+                                                      0x1a, 0x60, 0x90);
+                       break;
+               case 6:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
+                                                      0x12, 0x60, 0x90);
+                       break;
+               case 7:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
+                                                      0x3, 0x70, 0x90);
+                       break;
+               case 8:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x10,
+                                                      0x3, 0x70, 0x90);
+                       break;
+               case 9:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
+                                                      0x1a, 0xe1, 0x90);
+                       break;
+               case 10:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
+                                                      0x12, 0xe1, 0x90);
+                       break;
+               case 11:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
+                                                      0xa, 0xe1, 0x90);
+                       break;
+               case 12:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
+                                                      0x5, 0xe1, 0x90);
+                       break;
+               case 13:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
+                                                      0x1a, 0x60, 0x90);
+                       break;
+               case 14:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
+                                                      0x12, 0x60, 0x90);
+                       break;
+               case 15:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
+                                                      0xa, 0x60, 0x90);
+                       break;
+               case 16:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
+                                                      0x5, 0x60, 0x90);
+                       break;
+               case 17:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x2f,
+                                                      0x2f, 0x60, 0x90);
+                       break;
+               case 18:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
+                                                      0x5, 0xe1, 0x90);
+                       break;
+               case 19:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
+                                                      0x25, 0xe1, 0x90);
+                       break;
+               case 20:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
+                                                      0x25, 0x60, 0x90);
+                       break;
+               case 21:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15,
+                                                      0x03, 0x70, 0x90);
+                       break;
+               case 71:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
+                                                      0x1a, 0xe1, 0x90);
+                       break;
+               }
+       } else {
+               /* disable PS tdma */
+               switch (type) {
+               case 0:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
+                                                      0x40, 0x0);
+                       break;
+               case 1:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
+                                                      0x48, 0x0);
+                       break;
+               default:
+                       halbtc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
+                                                      0x40, 0x0);
+                       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 halbtc8723b2ant_coex_alloff(struct btc_coexist *btcoexist)
+{
+       /* fw all off */
+       halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+       halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       /* sw all off */
+       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false);
+       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
+
+       /* hw all off */
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+       halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
+void halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+       /* force to reset coex mechanism*/
+
+       halbtc8723b2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1);
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6);
+       halbtc8723b2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, false);
+
+       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false);
+       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
+}
+
+void halbtc8723b2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
+{
+       bool wifi_connected = false;
+       bool low_pwr_disable = true;
+
+       btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+                          &low_pwr_disable);
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+                          &wifi_connected);
+
+       if (wifi_connected) {
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
+       } else {
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
+       }
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6);
+       halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false);
+       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
+
+       coex_dm->need_recover_0x948 = true;
+       coex_dm->backup_0x948 = btcoexist->btc_read_2byte(btcoexist, 0x948);
+
+       halbtc8723b2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_AUX,
+                                    false, false);
+}
+
+bool halbtc8723b2ant_is_common_action(struct btc_coexist *btcoexist)
+{
+       bool bCommon = false, wifi_connected = false;
+       bool wifi_busy = false;
+       bool bt_hs_on = false, low_pwr_disable = false;
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+                          &wifi_connected);
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+       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");
+
+               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff,
+                                         0x0);
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
+               halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+               halbtc8723b2ant_sw_mechanism1(btcoexist, false, false, false,
+                                             false);
+               halbtc8723b2ant_sw_mechanism2(btcoexist, false, false, false,
+                                             0x18);
+
+               bCommon = true;
+       } else {
+               if (BT_8723B_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,
+                                 "[BTCoex], Wifi connected + "
+                                 "BT non connected-idle!!\n");
+
+                       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1,
+                                                 0xfffff, 0x0);
+                       halbtc8723b2ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 0);
+                       halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+                                               1);
+                       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC,
+                                                        0xb);
+                       halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
+                                                  false);
+
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+
+                       bCommon = true;
+               } else if (BT_8723B_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_hs_on)
+                               return false;
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Wifi connected + "
+                                 "BT connected-idle!!\n");
+
+                       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1,
+                                                 0xfffff, 0x0);
+                       halbtc8723b2ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 0);
+                       halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+                                               1);
+                       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC,
+                                                        0xb);
+                       halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
+                                                  false);
+
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+
+                       bCommon = 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,
+                                         "[BTCoex], Wifi Connected-Busy + "
+                                         "BT Busy!!\n");
+                               bCommon = false;
+                       } else {
+                               if(bt_hs_on)
+                                       return false;
+
+                               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                         "[BTCoex], Wifi Connected-Idle + "
+                                         "BT Busy!!\n");
+
+                               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A,
+                                                         0x1, 0xfffff, 0x0);
+                               halbtc8723b2ant_coex_table_with_type(btcoexist,
+                                                                   NORMAL_EXEC,
+                                                                   7);
+                               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+                                                       true, 21);
+                               halbtc8723b2ant_fw_dac_swing_lvl(btcoexist,
+                                                                NORMAL_EXEC,
+                                                                0xb);
+                               if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+                                       halbtc8723b2ant_dec_bt_pwr(btcoexist,
+                                                                  NORMAL_EXEC,
+                                                                  true);
+                               else
+                                       halbtc8723b2ant_dec_bt_pwr(btcoexist,
+                                                                  NORMAL_EXEC,
+                                                                  false);
+                               halbtc8723b2ant_sw_mechanism1(btcoexist, false,
+                                                             false, false,
+                                                             false);
+                               halbtc8723b2ant_sw_mechanism2(btcoexist, false,
+                                                             false, false,
+                                                             0x18);
+                               bCommon = true;
+                       }
+               }
+       }
+
+       return bCommon;
+}
+void halbtc8723b2ant_tdma_duration_adjust(struct btc_coexist *btcoexist,
+                                         bool sco_hid, bool tx_pause,
+                                         u8 max_interval)
+{
+       static s32 up, dn, m, n, wait_count;
+       /*0: no change, +1: increase WiFi duration, -1: decrease WiFi duration*/
+       s32 result;
+       u8 retryCount=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) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 13);
+                                       coex_dm->ps_tdma_du_adj_type = 13;
+                               }else if (max_interval == 2) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 14);
+                                       coex_dm->ps_tdma_du_adj_type = 14;
+                               } else if (max_interval == 3) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                       coex_dm->ps_tdma_du_adj_type = 15;
+                               } else {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                       coex_dm->ps_tdma_du_adj_type = 15;
+                               }
+                       } else {
+                               if(max_interval == 1) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 9);
+                                       coex_dm->ps_tdma_du_adj_type = 9;
+                               } else if (max_interval == 2) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 10);
+                                       coex_dm->ps_tdma_du_adj_type = 10;
+                               } else if (max_interval == 3) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                       coex_dm->ps_tdma_du_adj_type = 11;
+                               } else {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                       coex_dm->ps_tdma_du_adj_type = 11;
+                               }
+                       }
+               } else {
+                       if (tx_pause) {
+                               if (max_interval == 1) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 5);
+                                       coex_dm->ps_tdma_du_adj_type = 5;
+                               } else if (max_interval == 2) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                       coex_dm->ps_tdma_du_adj_type = 6;
+                               } else if (max_interval == 3) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                       coex_dm->ps_tdma_du_adj_type = 7;
+                               } else {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                       coex_dm->ps_tdma_du_adj_type = 7;
+                               }
+                       } else {
+                               if (max_interval == 1) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 1);
+                                       coex_dm->ps_tdma_du_adj_type = 1;
+                               } else if (max_interval == 2) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                       coex_dm->ps_tdma_du_adj_type = 2;
+                               } else if (max_interval == 3) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                       coex_dm->ps_tdma_du_adj_type = 3;
+                               } else {
+                                       halbtc8723b2ant_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_count = 0;
+       } else {
+               /*accquire the BT TRx retry count from BT_Info byte2*/
+               retryCount = coex_sta->bt_retry_cnt;
+               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, wait_count=%d\n",
+                         up, dn, m, n, wait_count);
+               result = 0;
+               wait_count++;
+                /* no retry in the last 2-second duration*/
+               if (retryCount == 0) {
+                       up++;
+                       dn--;
+
+                       if (dn <= 0)
+                               dn = 0;
+
+                       if (up >= n) {
+                               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");
+                       }/* <=3 retry in the last 2-second duration*/
+               } else if (retryCount <= 3) {
+                       up--;
+                       dn++;
+
+                       if (up <= 0)
+                               up = 0;
+
+                       if (dn == 2) {
+                               if (wait_count <= 2)
+                                       m++;
+                               else
+                                       m = 1;
+
+                               if (m >= 20)
+                                       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 {
+                       if (wait_count == 1)
+                               m++;
+                       else
+                               m = 1;
+
+                       if (m >= 20)
+                               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");
+               }
+
+               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) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 5);
+                                       coex_dm->ps_tdma_du_adj_type = 5;
+                               } else if (coex_dm->cur_ps_tdma == 1) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 5);
+                                       coex_dm->ps_tdma_du_adj_type = 5;
+                               } else if (coex_dm->cur_ps_tdma == 2) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                       coex_dm->ps_tdma_du_adj_type = 6;
+                               } else if (coex_dm->cur_ps_tdma == 3) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                       coex_dm->ps_tdma_du_adj_type = 7;
+                               } else if (coex_dm->cur_ps_tdma == 4) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 8);
+                                       coex_dm->ps_tdma_du_adj_type = 8;
+                               }
+
+                               if (coex_dm->cur_ps_tdma == 9) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 13);
+                                       coex_dm->ps_tdma_du_adj_type = 13;
+                               } else if (coex_dm->cur_ps_tdma == 10) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 14);
+                                       coex_dm->ps_tdma_du_adj_type = 14;
+                               } else if (coex_dm->cur_ps_tdma == 11) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                       coex_dm->ps_tdma_du_adj_type = 15;
+                               } else if (coex_dm->cur_ps_tdma == 12) {
+                                       halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             6;
+                                       } else if (coex_dm->cur_ps_tdma == 6) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 7) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 8);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             8;
+                                       } else if (coex_dm->cur_ps_tdma == 13) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 14);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            14;
+                                       } else if(coex_dm->cur_ps_tdma == 14) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            15;
+                                       } else if(coex_dm->cur_ps_tdma == 15) {
+                                               halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 7) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             6;
+                                       } else if(coex_dm->cur_ps_tdma == 6) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 5);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             5;
+                                       } else if(coex_dm->cur_ps_tdma == 16) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            15;
+                                       } else if(coex_dm->cur_ps_tdma == 15) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 14);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            14;
+                                       } else if(coex_dm->cur_ps_tdma == 14) {
+                                               halbtc8723b2ant_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) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 71);
+                                       coex_dm->ps_tdma_du_adj_type = 71;
+                               } else if (coex_dm->cur_ps_tdma == 6) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                       coex_dm->ps_tdma_du_adj_type = 2;
+                               } else if (coex_dm->cur_ps_tdma == 7) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                       coex_dm->ps_tdma_du_adj_type = 3;
+                               } else if (coex_dm->cur_ps_tdma == 8) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 4);
+                                       coex_dm->ps_tdma_du_adj_type = 4;
+                               }
+
+                               if (coex_dm->cur_ps_tdma == 13) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 9);
+                                       coex_dm->ps_tdma_du_adj_type = 9;
+                               } else if (coex_dm->cur_ps_tdma == 14) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 10);
+                                       coex_dm->ps_tdma_du_adj_type = 10;
+                               } else if (coex_dm->cur_ps_tdma == 15) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                       coex_dm->ps_tdma_du_adj_type = 11;
+                               } else if(coex_dm->cur_ps_tdma == 16) {
+                                       halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 1);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             1;
+                                       } else if (coex_dm->cur_ps_tdma == 1) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             2;
+                                       } else if (coex_dm->cur_ps_tdma == 2) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if(coex_dm->cur_ps_tdma == 3) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 4);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             4;
+                                       } else if(coex_dm->cur_ps_tdma == 9) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 10);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            10;
+                                       } else if (coex_dm->cur_ps_tdma == 10) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            11;
+                                       } else if (coex_dm->cur_ps_tdma == 11) {
+                                               halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if (coex_dm->cur_ps_tdma == 3) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             2;
+                                       } else if (coex_dm->cur_ps_tdma == 2) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 1);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             1;
+                                       } else if (coex_dm->cur_ps_tdma == 1) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 71);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            71;
+                                       } else if (coex_dm->cur_ps_tdma == 12) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            11;
+                                       } else if (coex_dm->cur_ps_tdma == 11) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 10);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            10;
+                                       } else if (coex_dm->cur_ps_tdma == 10) {
+                                               halbtc8723b2ant_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) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                       coex_dm->ps_tdma_du_adj_type = 6;
+                               } else if (coex_dm->cur_ps_tdma == 2) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                       coex_dm->ps_tdma_du_adj_type = 6;
+                               } else if (coex_dm->cur_ps_tdma == 3) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                       coex_dm->ps_tdma_du_adj_type = 7;
+                               } else if (coex_dm->cur_ps_tdma == 4) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 8);
+                                       coex_dm->ps_tdma_du_adj_type = 8;
+                               }
+                               if (coex_dm->cur_ps_tdma == 9) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 14);
+                                       coex_dm->ps_tdma_du_adj_type = 14;
+                               } else if (coex_dm->cur_ps_tdma == 10) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 14);
+                                       coex_dm->ps_tdma_du_adj_type = 14;
+                               } else if (coex_dm->cur_ps_tdma == 11) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                       coex_dm->ps_tdma_du_adj_type = 15;
+                               } else if (coex_dm->cur_ps_tdma == 12) {
+                                       halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             6;
+                                       } else if (coex_dm->cur_ps_tdma == 6) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 7) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 8);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             8;
+                                       } else if (coex_dm->cur_ps_tdma == 13) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 14);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            14;
+                                       } else if (coex_dm->cur_ps_tdma == 14) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            15;
+                                       } else if (coex_dm->cur_ps_tdma == 15) {
+                                               halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 7) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             6;
+                                       } else if (coex_dm->cur_ps_tdma == 6) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 6);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             6;
+                                       } else if (coex_dm->cur_ps_tdma == 16) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            15;
+                                       } else if (coex_dm->cur_ps_tdma == 15) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 14);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            14;
+                                       } else if (coex_dm->cur_ps_tdma == 14) {
+                                               halbtc8723b2ant_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) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                       coex_dm->ps_tdma_du_adj_type = 2;
+                               } else if (coex_dm->cur_ps_tdma == 6) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                       coex_dm->ps_tdma_du_adj_type = 2;
+                               } else if (coex_dm->cur_ps_tdma == 7) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                       coex_dm->ps_tdma_du_adj_type = 3;
+                               } else if (coex_dm->cur_ps_tdma == 8) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 4);
+                                       coex_dm->ps_tdma_du_adj_type = 4;
+                               }
+                               if (coex_dm->cur_ps_tdma == 13) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 10);
+                                       coex_dm->ps_tdma_du_adj_type = 10;
+                               } else if (coex_dm->cur_ps_tdma == 14){
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 10);
+                                       coex_dm->ps_tdma_du_adj_type = 10;
+                               } else if (coex_dm->cur_ps_tdma == 15) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                       coex_dm->ps_tdma_du_adj_type = 11;
+                               } else if (coex_dm->cur_ps_tdma == 16) {
+                                       halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             2;
+                                       } else if (coex_dm->cur_ps_tdma == 2) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if (coex_dm->cur_ps_tdma == 3) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 4);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             4;
+                                       } else if (coex_dm->cur_ps_tdma == 9) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 10);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            10;
+                                       } else if (coex_dm->cur_ps_tdma == 10) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            11;
+                                       } else if (coex_dm->cur_ps_tdma == 11) {
+                                               halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if (coex_dm->cur_ps_tdma == 3) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             2;
+                                       } else if (coex_dm->cur_ps_tdma == 2) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 2);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             2;
+                                       } else if (coex_dm->cur_ps_tdma == 12) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            11;
+                                       } else if (coex_dm->cur_ps_tdma == 11) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 10);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            10;
+                                       } else if (coex_dm->cur_ps_tdma == 10) {
+                                               halbtc8723b2ant_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) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                       coex_dm->ps_tdma_du_adj_type = 7;
+                               } else if (coex_dm->cur_ps_tdma == 2) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                       coex_dm->ps_tdma_du_adj_type = 7;
+                               } else if (coex_dm->cur_ps_tdma == 3) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                       coex_dm->ps_tdma_du_adj_type = 7;
+                               } else if (coex_dm->cur_ps_tdma == 4) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 8);
+                                       coex_dm->ps_tdma_du_adj_type = 8;
+                               }
+                               if (coex_dm->cur_ps_tdma == 9) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                       coex_dm->ps_tdma_du_adj_type = 15;
+                               } else if (coex_dm->cur_ps_tdma == 10) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                       coex_dm->ps_tdma_du_adj_type = 15;
+                               } else if (coex_dm->cur_ps_tdma == 11) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                       coex_dm->ps_tdma_du_adj_type = 15;
+                               } else if (coex_dm->cur_ps_tdma == 12) {
+                                       halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 6) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 7) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 8);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             8;
+                                       } else if (coex_dm->cur_ps_tdma == 13) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            15;
+                                       } else if (coex_dm->cur_ps_tdma == 14) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            15;
+                                       } else if (coex_dm->cur_ps_tdma == 15) {
+                                               halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 7) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 6) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 7);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             7;
+                                       } else if (coex_dm->cur_ps_tdma == 16) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            15;
+                                       } else if (coex_dm->cur_ps_tdma == 15) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 15);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            15;
+                                       } else if (coex_dm->cur_ps_tdma == 14) {
+                                               halbtc8723b2ant_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) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                       coex_dm->ps_tdma_du_adj_type = 3;
+                               } else if (coex_dm->cur_ps_tdma == 6) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                       coex_dm->ps_tdma_du_adj_type = 3;
+                               } else if (coex_dm->cur_ps_tdma == 7) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                       coex_dm->ps_tdma_du_adj_type = 3;
+                               } else if (coex_dm->cur_ps_tdma == 8) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 4);
+                                       coex_dm->ps_tdma_du_adj_type = 4;
+                               }
+                               if (coex_dm->cur_ps_tdma == 13) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                       coex_dm->ps_tdma_du_adj_type = 11;
+                               } else if (coex_dm->cur_ps_tdma == 14) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                       coex_dm->ps_tdma_du_adj_type = 11;
+                               } else if (coex_dm->cur_ps_tdma == 15) {
+                                       halbtc8723b2ant_ps_tdma(btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                       coex_dm->ps_tdma_du_adj_type = 11;
+                               } else if (coex_dm->cur_ps_tdma == 16) {
+                                       halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if (coex_dm->cur_ps_tdma == 2) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if (coex_dm->cur_ps_tdma == 3) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 4);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             4;
+                                       } else if (coex_dm->cur_ps_tdma == 9) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            11;
+                                       } else if (coex_dm->cur_ps_tdma == 10) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            11;
+                                       } else if (coex_dm->cur_ps_tdma == 11) {
+                                               halbtc8723b2ant_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) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if (coex_dm->cur_ps_tdma == 3) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if (coex_dm->cur_ps_tdma == 2) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 3);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                             3;
+                                       } else if (coex_dm->cur_ps_tdma == 12) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            11;
+                                       } else if (coex_dm->cur_ps_tdma == 11) {
+                                               halbtc8723b2ant_ps_tdma(
+                                                               btcoexist,
+                                                               NORMAL_EXEC,
+                                                               true, 11);
+                                               coex_dm->ps_tdma_du_adj_type =
+                                                                            11;
+                                       } else if (coex_dm->cur_ps_tdma == 10) {
+                                               halbtc8723b2ant_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!!!, "
+                         "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)
+                       halbtc8723b2ant_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 halbtc8723b2ant_action_sco(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+       /*for SCO quality at 11b/g mode*/
+       if (BTC_WIFI_BW_LEGACY == wifi_bw)
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+       else  /*for SCO quality & wifi performance balance at 11n mode*/
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 8);
+
+       /*for voice quality */
+       halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
+
+       /* sw mechanism */
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     true, 0x4);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     true, 0x4);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     true, 0x4);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     true, 0x4);
+               }
+       }
+}
+
+
+void halbtc8723b2ant_action_hid(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+       bt_rssi_state = halbtc8723b2ant_bt_rssi_state(2, 29, 0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+       if (BTC_WIFI_BW_LEGACY == wifi_bw) /*/for HID at 11b/g mode*/
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+       else  /*for HID quality & wifi performance balance at 11n mode*/
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 9);
+
+       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
+               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
+       else
+               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
+
+       /* sw mechanism */
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/
+void halbtc8723b2ant_action_a2dp(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state;
+       u32 wifi_bw;
+       u8 ap_num = 0;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+       wifi_rssi_state1 = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                          1, 2, 40, 0);
+       bt_rssi_state = halbtc8723b2ant_bt_rssi_state(2, 29, 0);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num);
+
+       /* define the office environment */
+       /* driver don't know AP num in Linux, so we will never enter this if */
+       if (ap_num >= 10 && BTC_RSSI_HIGH(wifi_rssi_state1)) {
+               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff,
+                                         0x0);
+               halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
+
+               /* sw mechanism */
+               btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+               if (BTC_WIFI_BW_HT40 == wifi_bw) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     true, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     true, 0x18);
+               }
+               return;
+       }
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+
+       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
+               halbtc8723b2ant_tdma_duration_adjust(btcoexist,false, false, 1);
+       else
+               halbtc8723b2ant_tdma_duration_adjust(btcoexist,false, true, 1);
+
+       /* sw mechanism */
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+
+       halbtc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 2);
+
+       /* sw mechanism */
+       btcoexist->btc_get(btcoexist,
+               BTC_GET_U4_WIFI_BW, &wifi_bw);
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false,0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+       bt_rssi_state = halbtc8723b2ant_bt_rssi_state(2, 29, 0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 10);
+
+       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
+               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1);
+       else
+               halbtc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
+
+       /* sw mechanism */
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+
+/*PAN(HS) only*/
+void halbtc8723b2ant_action_pan_hs(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+           (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+
+       halbtc8723b2ant_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 ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+/*PAN(EDR)+A2DP*/
+void halbtc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+       bt_rssi_state = halbtc8723b2ant_bt_rssi_state(2, 29, 0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+               halbtc8723b2ant_coex_table_with_type(btcoexist,NORMAL_EXEC, 12);
+               if (BTC_WIFI_BW_HT40 == wifi_bw)
+                       halbtc8723b2ant_tdma_duration_adjust(btcoexist, false,
+                                                            true, 3);
+               else
+                       halbtc8723b2ant_tdma_duration_adjust(btcoexist, false,
+                                                            false, 3);
+       } else {
+               halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+               halbtc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 3);
+       }
+
+       /* sw mechanism */
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, false,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+       bt_rssi_state = halbtc8723b2ant_bt_rssi_state(2, 29, 0);
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+               if (BTC_WIFI_BW_HT40 == wifi_bw) {
+                       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC,
+                                                        3);
+                       halbtc8723b2ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 11);
+                       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1,
+                                                 0xfffff, 0x780);
+               } else {
+                       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC,
+                                                        6);
+                       halbtc8723b2ant_coex_table_with_type(btcoexist,
+                                                            NORMAL_EXEC, 7);
+                       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1,
+                                                 0xfffff, 0x0);
+               }
+               halbtc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2);
+       } else {
+               halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+               halbtc8723b2ant_coex_table_with_type(btcoexist,NORMAL_EXEC, 11);
+               btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff,
+                                         0x0);
+               halbtc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2);
+       }
+
+       /* sw mechanism */
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)){
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+/* HID+A2DP+PAN(EDR) */
+void halbtc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+       bt_rssi_state = halbtc8723b2ant_bt_rssi_state(2, 29, 0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+       halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+
+       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+               if (BTC_WIFI_BW_HT40 == wifi_bw)
+                       halbtc8723b2ant_tdma_duration_adjust(btcoexist, true,
+                                                            true, 2);
+               else
+                       halbtc8723b2ant_tdma_duration_adjust(btcoexist, true,
+                                                            false, 3);
+       } else {
+               halbtc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 3);
+       }
+
+       /* sw mechanism */
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+{
+       u8 wifi_rssi_state, bt_rssi_state;
+       u32 wifi_bw;
+
+       wifi_rssi_state = halbtc8723b2ant_wifi_rssi_state(btcoexist,
+                                                         0, 2, 15, 0);
+       bt_rssi_state = halbtc8723b2ant_bt_rssi_state(2, 29, 0);
+
+       btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
+
+       halbtc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
+
+       if (halbtc8723b2ant_need_to_dec_bt_pwr(btcoexist))
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
+       else
+               halbtc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+       halbtc8723b2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+
+       if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
+           (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
+               halbtc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2);
+       else
+               halbtc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2);
+
+       /* sw mechanism */
+       if (BTC_WIFI_BW_HT40 == wifi_bw) {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, true, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       } else {
+               if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+                   (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, true, false,
+                                                     false, 0x18);
+               } else {
+                       halbtc8723b2ant_sw_mechanism1(btcoexist, false, true,
+                                                     false, false);
+                       halbtc8723b2ant_sw_mechanism2(btcoexist, false, false,
+                                                     false, 0x18);
+               }
+       }
+}
+
+void halbtc8723b2ant_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], RunCoexistMechanism(), "
+                         "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 = halbtc8723b2ant_action_algorithm(btcoexist);
+       if (coex_sta->c2h_bt_inquiry_page &&
+           (BT_8723B_2ANT_COEX_ALGO_PANHS != algorithm)) {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BT is under inquiry/page scan !!\n");
+               halbtc8723b2ant_action_bt_inquiry(btcoexist);
+               return;
+       } else {
+               if (coex_dm->need_recover_0x948) {
+                       coex_dm->need_recover_0x948 = false;
+                       btcoexist->btc_write_2byte(btcoexist, 0x948,
+                                                  coex_dm->backup_0x948);
+               }
+       }
+
+       coex_dm->cur_algorithm = algorithm;
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, "[BTCoex], Algorithm = %d \n",
+                 coex_dm->cur_algorithm);
+
+       if (halbtc8723b2ant_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_8723B_2ANT_COEX_ALGO_SCO:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, algorithm = SCO.\n");
+                       halbtc8723b2ant_action_sco(btcoexist);
+                       break;
+               case BT_8723B_2ANT_COEX_ALGO_HID:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, algorithm = HID.\n");
+                       halbtc8723b2ant_action_hid(btcoexist);
+                       break;
+               case BT_8723B_2ANT_COEX_ALGO_A2DP:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = A2DP.\n");
+                       halbtc8723b2ant_action_a2dp(btcoexist);
+                       break;
+               case BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = A2DP+PAN(HS).\n");
+                       halbtc8723b2ant_action_a2dp_pan_hs(btcoexist);
+                       break;
+               case BT_8723B_2ANT_COEX_ALGO_PANEDR:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = PAN(EDR).\n");
+                       halbtc8723b2ant_action_pan_edr(btcoexist);
+                       break;
+               case BT_8723B_2ANT_COEX_ALGO_PANHS:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = HS mode.\n");
+                       halbtc8723b2ant_action_pan_hs(btcoexist);
+                               break;
+               case BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = PAN+A2DP.\n");
+                       halbtc8723b2ant_action_pan_edr_a2dp(btcoexist);
+                       break;
+               case BT_8723B_2ANT_COEX_ALGO_PANEDR_HID:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = PAN(EDR)+HID.\n");
+                       halbtc8723b2ant_action_pan_edr_hid(btcoexist);
+                       break;
+               case BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = HID+A2DP+PAN.\n");
+                       halbtc8723b2ant_action_hid_a2dp_pan_edr(btcoexist);
+                       break;
+               case BT_8723B_2ANT_COEX_ALGO_HID_A2DP:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = HID+A2DP.\n");
+                       halbtc8723b2ant_action_hid_a2dp(btcoexist);
+                       break;
+               default:
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], Action 2-Ant, "
+                                 "algorithm = coexist All Off!!\n");
+                       halbtc8723b2ant_coex_alloff(btcoexist);
+                       break;
+               }
+               coex_dm->pre_algorithm = coex_dm->cur_algorithm;
+       }
+}
+
+void halbtc8723b2ant_wifioff_hwcfg(struct btc_coexist *btcoexist)
+{
+       /* set wlan_act to low */
+       btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
+       /* Force GNT_BT to High */
+       btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3);
+       /* BT select s0/s1 is controlled by BT */
+       btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0);
+}
+
+/*********************************************************************
+ *  work around function start with wa_halbtc8723b2ant_
+ *********************************************************************/
+/*********************************************************************
+ *  extern function start with EXhalbtc8723b2ant_
+ *********************************************************************/
+void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist)
+{
+       u8 u8tmp = 0;
+
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                 "[BTCoex], 2Ant Init HW Config!!\n");
+       coex_dm->bt_rf0x1e_backup =
+               btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff);
+
+       /* 0x790[5:0]=0x5 */
+       u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
+       u8tmp &= 0xc0;
+       u8tmp |= 0x5;
+       btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp);
+
+
+       /*Antenna config        */
+       halbtc8723b2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_MAIN,
+                                    true, false);
+
+
+
+
+       /* PTA parameter */
+       halbtc8723b2ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+
+       /* Enable counter statistics */
+       /*0x76e[3] =1, WLAN_Act control by PTA*/
+       btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+       btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3);
+       btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
+}
+
+void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                 "[BTCoex], Coex Mechanism Init!!\n");
+       halbtc8723b2ant_init_coex_dm(btcoexist);
+}
+
+void ex_halbtc8723b2ant_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;
+       struct btc_bt_link_info* bt_link_info = &btcoexist->bt_link_info;
+       u8 *cli_buf = btcoexist->cli_buf;
+       u8 u8tmp[4], i, bt_info_ext, ps_tdma_case=0;
+       u32 u32tmp[4];
+       bool roam = false, scan = false;
+       bool link = false, wifi_under_5g = false;
+       bool bt_hs_on = false, wifi_busy = false;
+       s32 wifi_rssi = 0, bt_hs_rssi = 0;
+       u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck;
+       u8 wifi_dot11_chnl, wifi_hs_chnl;
+       u32 fw_ver = 0, bt_patch_ver = 0;
+       u8 ap_num = 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_%x/ 0x%x/ 0x%x(%d)",
+                  "CoexVer/ fw_ver/ PatchVer",
+                  glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant,
+                  fw_ver, bt_patch_ver, bt_patch_ver);
+       CL_PRINTF(cli_buf);
+
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+       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 / HsChnl(HsMode)",
+                  wifi_dot11_chnl, wifi_hs_chnl, 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);
+       btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d",
+                  "Wifi rssi/ HS rssi/ AP#", wifi_rssi, bt_hs_rssi, ap_num);
+       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_PRINTF(cli_buf);
+
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d",
+                  "SCO/HID/PAN/A2DP",
+                  bt_link_info->sco_exist, bt_link_info->hid_exist,
+                  bt_link_info->pan_exist, bt_link_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_8723B_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 %02x %02x %02x(%d)",
+                                  glbt_info_src_8723b_2ant[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",
+                  "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);
+
+       /* 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);
+
+       /* 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);
+
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+                  "0x778/0x880[29:25]", u8tmp[0],
+                  (u32tmp[0]&0x3e000000) >> 25);
+       CL_PRINTF(cli_buf);
+
+
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948);
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67);
+       u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+                  "0x948/ 0x67[5] / 0x765",
+                  u32tmp[0], ((u8tmp[0]&0x20)>> 5), u8tmp[1]);
+       CL_PRINTF(cli_buf);
+
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c);
+       u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930);
+       u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+                  "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]",
+                  u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3);
+       CL_PRINTF(cli_buf);
+
+
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39);
+       u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+       u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+                  "0x38[11]/0x40/0x4c[24:23]/0x64[0]",
+                  ((u8tmp[0] & 0x8)>>3), u8tmp[1],
+                  ((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1);
+       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);
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c);
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+                  "0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]);
+       CL_PRINTF(cli_buf);
+
+       u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0);
+       u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4);
+       u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8);
+       u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0);
+
+       u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b);
+       u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
+
+       fa_ofdm = ((u32tmp[0]&0xffff0000) >> 16) +
+                 ((u32tmp[1]&0xffff0000) >> 16) +
+                  (u32tmp[1] & 0xffff) +
+                  (u32tmp[2] & 0xffff) +
+                 ((u32tmp[3]&0xffff0000) >> 16) +
+                  (u32tmp[3] & 0xffff) ;
+       fa_cck = (u8tmp[0] << 8) + u8tmp[1];
+
+       CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+                  "OFDM-CCA/OFDM-FA/CCK-FA", \
+                  u32tmp[0]&0xffff, fa_ofdm, fa_cck);
+       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(high-pri rx/tx)",
+                  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(low-pri rx/tx)", coex_sta->low_priority_rx,
+                  coex_sta->low_priority_tx);
+       CL_PRINTF(cli_buf);
+#if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 1)
+       halbtc8723b2ant_monitor_bt_ctr(btcoexist);
+#endif
+       btcoexist->btc_disp_dbg_msg(btcoexist,
+       BTC_DBG_DISP_COEX_STATISTICS);
+}
+
+
+void ex_halbtc8723b2ant_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;
+               halbtc8723b2ant_wifioff_hwcfg(btcoexist);
+               halbtc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
+               halbtc8723b2ant_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;
+               ex_halbtc8723b2ant_init_hwconfig(btcoexist);
+               halbtc8723b2ant_init_coex_dm(btcoexist);
+               halbtc8723b2ant_query_bt_info(btcoexist);
+       }
+}
+
+void ex_halbtc8723b2ant_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_halbtc8723b2ant_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_halbtc8723b2ant_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_halbtc8723b2ant_media_status_notify(struct btc_coexist *btcoexist,
+                                           u8 type)
+{
+       u8 h2c_parameter[3] ={0};
+       u32 wifi_bw;
+       u8 wifi_central_chnl;
+
+       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_central_chnl);
+       if ((BTC_MEDIA_CONNECT == type) &&
+           (wifi_central_chnl <= 14)) {
+               h2c_parameter[0] = 0x1;
+               h2c_parameter[1] = wifi_central_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_halbtc8723b2ant_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_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
+                                      u8 *tmpbuf, u8 length)
+{
+       u8 btInfo = 0;
+       u8 i, rsp_source = 0;
+       bool bt_busy = false, limited_dig = false;
+       bool wifi_connected = false;
+
+       coex_sta->c2h_bt_info_req_sent = false;
+
+       rsp_source = tmpbuf[0]&0xf;
+       if(rsp_source >= BT_INFO_SRC_8723B_2ANT_MAX)
+               rsp_source = BT_INFO_SRC_8723B_2ANT_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] = 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 (btcoexist->manual_control) {
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), "
+                         "return for Manual CTRL<===\n");
+               return;
+       }
+
+       if (BT_INFO_SRC_8723B_2ANT_WIFI_FW != rsp_source) {
+               coex_sta->bt_retry_cnt =        /* [3:0]*/
+                       coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
+
+               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)) {
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], BT ext info bit1 check,"
+                                 " send wifi BW&Chnl to BT!!\n");
+                       btcoexist->btc_get(btcoexist,BTC_GET_BL_WIFI_CONNECTED,
+                                          &wifi_connected);
+                       if (wifi_connected)
+                               ex_halbtc8723b2ant_media_status_notify(
+                                                       btcoexist,
+                                                       BTC_MEDIA_CONNECT);
+                       else
+                               ex_halbtc8723b2ant_media_status_notify(
+                                                       btcoexist,
+                                                       BTC_MEDIA_DISCONNECT);
+               }
+
+               if ((coex_sta->bt_info_ext & BIT3)) {
+                       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                                 "[BTCoex], BT ext info bit3 check, "
+                                 "set BT NOT to ignore Wlan active!!\n");
+                       halbtc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC,
+                                                       false);
+               } else {
+                       /* BT already NOT ignore Wlan active, do nothing here.*/
+               }
+#if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 0)
+               if ((coex_sta->bt_info_ext & BIT4)) {
+                       /* BT auto report already enabled, do nothing*/
+               } else {
+                       halbtc8723b2ant_bt_auto_report(btcoexist, FORCE_EXEC,
+                                                      true);
+               }
+#endif
+       }
+
+       /* check BIT2 first ==> check if bt is under inquiry or page scan*/
+       if (btInfo & BT_INFO_8723B_2ANT_B_INQ_PAGE)
+               coex_sta->c2h_bt_inquiry_page = true;
+       else
+               coex_sta->c2h_bt_inquiry_page = false;
+
+       /* set link exist status*/
+       if (!(btInfo & BT_INFO_8723B_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 (btInfo & BT_INFO_8723B_2ANT_B_FTP)
+                       coex_sta->pan_exist = true;
+               else
+                       coex_sta->pan_exist = false;
+               if (btInfo & BT_INFO_8723B_2ANT_B_A2DP)
+                       coex_sta->a2dp_exist = true;
+               else
+                       coex_sta->a2dp_exist = false;
+               if (btInfo & BT_INFO_8723B_2ANT_B_HID)
+                       coex_sta->hid_exist = true;
+               else
+                       coex_sta->hid_exist = false;
+               if (btInfo & BT_INFO_8723B_2ANT_B_SCO_ESCO)
+                       coex_sta->sco_exist = true;
+               else
+                       coex_sta->sco_exist = false;
+       }
+
+       halbtc8723b2ant_update_bt_link_info(btcoexist);
+
+       if (!(btInfo & BT_INFO_8723B_2ANT_B_CONNECTION)) {
+               coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), "
+                         "BT Non-Connected idle!!!\n");
+       /* connection exists but no busy */
+       } else if (btInfo == BT_INFO_8723B_2ANT_B_CONNECTION) {
+               coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
+       } else if ((btInfo & BT_INFO_8723B_2ANT_B_SCO_ESCO) ||
+                  (btInfo & BT_INFO_8723B_2ANT_B_SCO_BUSY)) {
+               coex_dm->bt_status =
+                       BT_8723B_2ANT_BT_STATUS_SCO_BUSY;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
+       } else if (btInfo&BT_INFO_8723B_2ANT_B_ACL_BUSY) {
+               coex_dm->bt_status =
+                       BT_8723B_2ANT_BT_STATUS_ACL_BUSY;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
+       } else {
+               coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_MAX;
+               BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                         "[BTCoex], BtInfoNotify(), "
+                         "BT Non-Defined state!!!\n");
+       }
+
+       if ((BT_8723B_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
+           (BT_8723B_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+           (BT_8723B_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);
+
+       halbtc8723b2ant_run_coexist_mechanism(btcoexist);
+}
+
+void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist)
+{
+       BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n");
+
+       halbtc8723b2ant_wifioff_hwcfg(btcoexist);
+       halbtc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
+       ex_halbtc8723b2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
+}
+
+void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist)
+{
+       struct btc_board_info *board_info = &btcoexist->board_info;
+       struct btc_stack_info *stack_info = &btcoexist->stack_info;
+       static u8 dis_ver_info_cnt = 0;
+       u32 fw_ver = 0, bt_patch_ver = 0;
+
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+                 "[BTCoex], =========================="
+                 "Periodical===========================\n");
+
+       if (dis_ver_info_cnt <= 5) {
+               dis_ver_info_cnt += 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", board_info->pg_ant_num,
+                         board_info->btdm_ant_num, board_info->btdm_ant_pos);
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                         "[BTCoex], 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,
+                         "[BTCoex], CoexVer/ fw_ver/ PatchVer = "
+                         "%d_%x/ 0x%x/ 0x%x(%d)\n",
+                         glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant,
+                         fw_ver, bt_patch_ver, bt_patch_ver);
+               BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+                         "[BTCoex], *****************************"
+                         "***********************************\n");
+       }
+
+#if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 0)
+       halbtc8723b2ant_query_bt_info(btcoexist);
+       halbtc8723b2ant_monitor_bt_ctr(btcoexist);
+       halbtc8723b2ant_monitor_bt_enable_disable(btcoexist);
+#else
+       if (halbtc8723b2ant_is_wifi_status_changed(btcoexist) ||
+           coex_dm->auto_tdma_adjust)
+               halbtc8723b2ant_run_coexist_mechanism(btcoexist);
+#endif
+}
+
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8723b2ant.h b/drivers/staging/rtl8821ae/btcoexist/halbtc8723b2ant.h
new file mode 100644 (file)
index 0000000..fa3784a
--- /dev/null
@@ -0,0 +1,145 @@
+/************************************************************************
+ * The following is for 8723B 2Ant BT Co-exist definition
+ ************************************************************************/
+#define        BT_AUTO_REPORT_ONLY_8723B_2ANT                  1
+
+
+#define        BT_INFO_8723B_2ANT_B_FTP                        BIT7
+#define        BT_INFO_8723B_2ANT_B_A2DP                       BIT6
+#define        BT_INFO_8723B_2ANT_B_HID                        BIT5
+#define        BT_INFO_8723B_2ANT_B_SCO_BUSY                   BIT4
+#define        BT_INFO_8723B_2ANT_B_ACL_BUSY                   BIT3
+#define        BT_INFO_8723B_2ANT_B_INQ_PAGE                   BIT2
+#define        BT_INFO_8723B_2ANT_B_SCO_ESCO                   BIT1
+#define        BT_INFO_8723B_2ANT_B_CONNECTION                 BIT0
+
+#define BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT            2
+
+typedef enum _BT_INFO_SRC_8723B_2ANT{
+       BT_INFO_SRC_8723B_2ANT_WIFI_FW                  = 0x0,
+       BT_INFO_SRC_8723B_2ANT_BT_RSP                   = 0x1,
+       BT_INFO_SRC_8723B_2ANT_BT_ACTIVE_SEND           = 0x2,
+       BT_INFO_SRC_8723B_2ANT_MAX
+}BT_INFO_SRC_8723B_2ANT,*PBT_INFO_SRC_8723B_2ANT;
+
+typedef enum _BT_8723B_2ANT_BT_STATUS{
+       BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE      = 0x0,
+       BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE          = 0x1,
+       BT_8723B_2ANT_BT_STATUS_INQ_PAGE                = 0x2,
+       BT_8723B_2ANT_BT_STATUS_ACL_BUSY                = 0x3,
+       BT_8723B_2ANT_BT_STATUS_SCO_BUSY                = 0x4,
+       BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY            = 0x5,
+       BT_8723B_2ANT_BT_STATUS_MAX
+}BT_8723B_2ANT_BT_STATUS,*PBT_8723B_2ANT_BT_STATUS;
+
+typedef enum _BT_8723B_2ANT_COEX_ALGO{
+       BT_8723B_2ANT_COEX_ALGO_UNDEFINED               = 0x0,
+       BT_8723B_2ANT_COEX_ALGO_SCO                     = 0x1,
+       BT_8723B_2ANT_COEX_ALGO_HID                     = 0x2,
+       BT_8723B_2ANT_COEX_ALGO_A2DP                    = 0x3,
+       BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS              = 0x4,
+       BT_8723B_2ANT_COEX_ALGO_PANEDR                  = 0x5,
+       BT_8723B_2ANT_COEX_ALGO_PANHS                   = 0x6,
+       BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP             = 0x7,
+       BT_8723B_2ANT_COEX_ALGO_PANEDR_HID              = 0x8,
+       BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR         = 0x9,
+       BT_8723B_2ANT_COEX_ALGO_HID_A2DP                = 0xa,
+       BT_8723B_2ANT_COEX_ALGO_MAX                     = 0xb,
+}BT_8723B_2ANT_COEX_ALGO,*PBT_8723B_2ANT_COEX_ALGO;
+
+struct coex_dm_8723b_2ant{
+       /* fw mechanism */
+       bool pre_dec_bt_pwr;
+       bool 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;
+
+       /* algorithm related */
+       u8 pre_algorithm;
+       u8 cur_algorithm;
+       u8 bt_status;
+       u8 wifi_chnl_info[3];
+
+       bool need_recover_0x948;
+       u16 backup_0x948;
+};
+
+struct coex_sta_8723b_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_8723B_2ANT_MAX][10];
+       u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_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_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist);
+void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist);
+void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8723b2ant_media_status_notify(struct btc_coexist *btcoexist,
+                                           u8 type);
+void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist,
+                                             u8 type);
+void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
+                                      u8 *tmpbuf, u8 length);
+void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist);
+void ex_halbtc8723b2ant_periodical(struct btc_coexist * btcoexist);
+void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist);
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.c b/drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.c
new file mode 100644 (file)
index 0000000..9d9fa4d
--- /dev/null
@@ -0,0 +1,1181 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2013 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
+ *
+ *
+ ******************************************************************************/
+
+#include "halbt_precomp.h"
+
+/*#if(BT_30_SUPPORT == 1)*/
+#if 1
+/***********************************************
+ *             Global variables
+ ***********************************************/
+const char *const bt_profile_string[]={
+       "NONE",
+       "A2DP",
+       "PAN",
+       "HID",
+       "SCO",
+};
+
+const char *const bt_spec_string[]={
+       "1.0b",
+       "1.1",
+       "1.2",
+       "2.0+EDR",
+       "2.1+EDR",
+       "3.0+HS",
+       "4.0",
+};
+
+const char *const bt_link_role_string[]={
+       "Master",
+       "Slave",
+};
+
+const char *const h2c_state_string[]={
+       "successful",
+       "h2c busy",
+       "rf off",
+       "fw not read",
+};
+
+const char *const io_state_string[]={
+       "IO_STATUS_SUCCESS",
+       "IO_STATUS_FAIL_CANNOT_IO",
+       "IO_STATUS_FAIL_RF_OFF",
+       "IO_STATUS_FAIL_FW_READ_CLEAR_TIMEOUT",
+       "IO_STATUS_FAIL_WAIT_IO_EVENT_TIMEOUT",
+       "IO_STATUS_INVALID_LEN",
+       "IO_STATUS_IO_IDLE_QUEUE_EMPTY",
+       "IO_STATUS_IO_INSERT_WAIT_QUEUE_FAIL",
+       "IO_STATUS_UNKNOWN_FAIL",
+       "IO_STATUS_WRONG_LEVEL",
+       "IO_STATUS_H2C_STOPPED",
+};
+
+struct btc_coexist gl_bt_coexist;
+
+u32 btc_dbg_type[BTC_MSG_MAX];
+u8 btc_dbg_buf[100];
+
+/***************************************************
+ *             Debug related function
+ ***************************************************/
+bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist)
+{
+       if (!btcoexist->binded || NULL == btcoexist->adapter)
+               return false;
+       
+       return true;
+}
+
+bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv)
+{
+
+       if (rtlpriv->link_info.b_busytraffic)
+               return true;
+       else
+               return false;
+}
+
+
+void halbtc_dbg_init(void)
+{
+       u8 i;
+
+       for (i = 0; i < BTC_MSG_MAX; i++)
+               btc_dbg_type[i] = 0;
+
+       btc_dbg_type[BTC_MSG_INTERFACE]                 =       \
+//                     INTF_INIT                               |
+//                     INTF_NOTIFY                             |
+                       0;
+       
+       btc_dbg_type[BTC_MSG_ALGORITHM]                 =       \
+//                     ALGO_BT_RSSI_STATE                      |
+//                     ALGO_WIFI_RSSI_STATE                    |
+//                     ALGO_BT_MONITOR                         |
+//                     ALGO_TRACE                              |
+//                     ALGO_TRACE_FW                           |
+//                     ALGO_TRACE_FW_DETAIL                    |
+//                     ALGO_TRACE_FW_EXEC                      |
+//                     ALGO_TRACE_SW                           |
+//                     ALGO_TRACE_SW_DETAIL                    |
+//                     ALGO_TRACE_SW_EXEC                      |
+                       0;
+}
+
+bool halbtc_is_hw_mailbox_exist(struct btc_coexist *btcoexist)
+{
+       return true;
+}
+
+bool halbtc_is_bt40(struct rtl_priv *adapter)
+{
+       struct rtl_priv *rtlpriv = adapter;
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       bool is_ht40 = true;
+       enum ht_channel_width bw = rtlphy->current_chan_bw;
+       
+       
+       if (bw == HT_CHANNEL_WIDTH_20)
+               is_ht40 = false;
+       else if (bw == HT_CHANNEL_WIDTH_20_40)
+               is_ht40 = true;
+
+       return is_ht40;
+}
+
+bool halbtc_legacy(struct rtl_priv *adapter)
+{
+       struct rtl_priv *rtlpriv = adapter;
+       struct rtl_mac *mac = rtl_mac(rtlpriv);
+       
+       bool is_legacy = false;
+
+       if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_B))
+               is_legacy = true;
+
+       return is_legacy;
+}
+
+bool halbtc_is_wifi_uplink(struct rtl_priv *adapter)
+{
+       struct rtl_priv *rtlpriv = adapter;
+       
+       if (rtlpriv->link_info.b_tx_busy_traffic)
+               return true;
+       else
+               return false;
+}
+
+u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv = 
+               (struct rtl_priv *)btcoexist->adapter;
+       u32 wifi_bw = BTC_WIFI_BW_HT20;
+       
+       if (halbtc_is_bt40(rtlpriv)){
+               wifi_bw = BTC_WIFI_BW_HT40;     
+       } else {
+               if(halbtc_legacy(rtlpriv))
+                       wifi_bw = BTC_WIFI_BW_LEGACY;
+               else
+                       wifi_bw = BTC_WIFI_BW_HT20;
+       }
+       return wifi_bw;
+}
+
+u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_phy  *rtlphy = &(rtlpriv->phy);
+       u8 chnl = 1;
+       
+
+       if (rtlphy->current_channel != 0)
+               chnl = rtlphy->current_channel;
+       BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, 
+                 "halbtc_get_wifi_central_chnl:%d\n",chnl);
+       return chnl;
+}
+
+void halbtc_leave_lps(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv;
+       struct rtl_ps_ctl *ppsc;
+       bool ap_enable = false;
+       
+       rtlpriv = btcoexist->adapter;
+       ppsc = rtl_psc(rtlpriv);
+       
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+                          &ap_enable);
+       
+       if (ap_enable) {
+               printk("halbtc_leave_lps()<--dont leave lps under AP mode\n");
+               return;
+       }
+
+       btcoexist->bt_info.bt_ctrl_lps = true;
+       btcoexist->bt_info.bt_lps_on = false;
+}
+
+void halbtc_enter_lps(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv;
+       struct rtl_ps_ctl *ppsc;
+       bool ap_enable = false;
+       
+       rtlpriv = btcoexist->adapter;
+       ppsc = rtl_psc(rtlpriv);
+       
+       btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, 
+                          &ap_enable);
+       
+       if (ap_enable) {
+               printk("halbtc_enter_lps()<--dont enter lps under AP mode\n");
+               return;
+       }
+       
+       btcoexist->bt_info.bt_ctrl_lps = true;
+       btcoexist->bt_info.bt_lps_on = false;
+}
+
+void halbtc_normal_lps(struct btc_coexist *btcoexist)
+{
+       if (btcoexist->bt_info.bt_ctrl_lps) {
+               btcoexist->bt_info.bt_lps_on = false;
+               btcoexist->bt_info.bt_ctrl_lps = false;
+       }
+               
+}
+
+void halbtc_leave_low_power(void)
+{
+}
+
+void halbtc_nomal_low_power(void)
+{
+}
+
+void halbtc_disable_low_power(void)
+{
+}
+
+void halbtc_aggregation_check(void)
+{
+}
+
+
+u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist)
+{
+       return 0;
+}
+
+s32 halbtc_get_wifi_rssi(struct rtl_priv *adapter)
+{
+       struct rtl_priv *rtlpriv = adapter;
+       s32     undecorated_smoothed_pwdb = 0;
+       
+       if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
+               undecorated_smoothed_pwdb = 
+                       rtlpriv->dm.undecorated_smoothed_pwdb;
+       else /* associated entry pwdb */
+               undecorated_smoothed_pwdb =
+                       rtlpriv->dm.undecorated_smoothed_pwdb;
+       return undecorated_smoothed_pwdb;
+}
+
+bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtlpriv);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       bool *bool_tmp = (bool*)out_buf;
+       int *s32_tmp = (int*)out_buf;
+       u32 *u32_tmp = (u32*)out_buf;
+       u8 *u8_tmp = (u8*)out_buf;
+       bool tmp = false;
+
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return false;
+       
+
+       switch (get_type){
+       case BTC_GET_BL_HS_OPERATION:
+               *bool_tmp = false;
+               break;
+       case BTC_GET_BL_HS_CONNECTING:
+               *bool_tmp = false;
+               break;
+       case BTC_GET_BL_WIFI_CONNECTED:
+               if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
+                       tmp = true;
+                               
+               *bool_tmp = tmp;
+               break;
+       case BTC_GET_BL_WIFI_BUSY:
+               if(halbtc_is_wifi_busy(rtlpriv))
+                       *bool_tmp = true;
+               else
+                       *bool_tmp = false;
+               break;
+       case BTC_GET_BL_WIFI_SCAN:
+               if (mac->act_scanning == true)
+                       *bool_tmp = true;
+               else
+                       *bool_tmp = false;
+               break;
+       case BTC_GET_BL_WIFI_LINK:
+               if (mac->link_state == MAC80211_LINKING)
+                       *bool_tmp = true;
+               else
+                       *bool_tmp = false;
+               break;
+       case BTC_GET_BL_WIFI_ROAM:      /*TODO*/
+               if (mac->link_state == MAC80211_LINKING)
+                       *bool_tmp = true;
+               else
+                       *bool_tmp = false;
+               break;
+       case BTC_GET_BL_WIFI_4_WAY_PROGRESS:    /*TODO*/
+                       *bool_tmp = false;
+
+               break;
+       case BTC_GET_BL_WIFI_UNDER_5G:
+               *bool_tmp = false; /*TODO*/
+               
+       case BTC_GET_BL_WIFI_DHCP:      /*TODO*/
+               break;
+       case BTC_GET_BL_WIFI_SOFTAP_IDLE:
+               *bool_tmp = true;
+               break;
+       case BTC_GET_BL_WIFI_SOFTAP_LINKING:
+               *bool_tmp = false;
+               break;
+       case BTC_GET_BL_WIFI_IN_EARLY_SUSPEND:
+               *bool_tmp = false;
+               break;
+       case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
+               *bool_tmp = false;
+               break;
+       case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
+               if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm)
+                       *bool_tmp = false;
+               else
+                       *bool_tmp = true;
+               break;
+       case BTC_GET_BL_WIFI_UNDER_B_MODE:
+               *bool_tmp = false; /*TODO*/
+               break;
+       case BTC_GET_BL_EXT_SWITCH:
+               *bool_tmp = false;
+               break;
+       case BTC_GET_S4_WIFI_RSSI:
+               *s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
+               break;
+       case BTC_GET_S4_HS_RSSI:        /*TODO*/
+               *s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
+               break;
+       case BTC_GET_U4_WIFI_BW:
+               *u32_tmp = halbtc_get_wifi_bw(btcoexist);
+               break;
+       case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION:
+               if (halbtc_is_wifi_uplink(rtlpriv))
+                       *u32_tmp = BTC_WIFI_TRAFFIC_TX;
+               else
+                       *u32_tmp = BTC_WIFI_TRAFFIC_RX;
+               break;
+       case BTC_GET_U4_WIFI_FW_VER:
+               *u32_tmp = rtlhal->fw_version;
+               break;
+       case BTC_GET_U4_BT_PATCH_VER:
+               *u32_tmp = halbtc_get_bt_patch_version(btcoexist);
+               break;
+       case BTC_GET_U1_WIFI_DOT11_CHNL:
+               *u8_tmp = rtlphy->current_channel;
+               break;
+       case BTC_GET_U1_WIFI_CENTRAL_CHNL:
+               *u8_tmp = halbtc_get_wifi_central_chnl(btcoexist);
+               break;
+       case BTC_GET_U1_WIFI_HS_CHNL:
+               *u8_tmp = 1;/* BT_OperateChnl(rtlpriv); */
+               break;
+       case BTC_GET_U1_MAC_PHY_MODE:
+               *u8_tmp = BTC_MP_UNKNOWN;
+               break;
+       case BTC_GET_U1_AP_NUM:
+               /* driver don't know AP num in Linux, 
+                * So, the return value here is not right */
+               *u8_tmp = 1;/* pDefMgntInfo->NumBssDesc4Query; */
+               break;
+
+       /************* 1Ant **************/
+       case BTC_GET_U1_LPS_MODE:
+               *u8_tmp = btcoexist->pwr_mode_val[0];
+               break;
+                                       
+       default:
+               break;
+       }
+       
+       return true;
+}
+
+bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
+       bool *bool_tmp = (bool *)in_buf;
+       u8 *u8_tmp = (u8 *)in_buf;
+       u32 *u32_tmp = (u32 *)in_buf;
+       
+       
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return false;
+
+       switch (set_type) {
+       /* set some bool type variables. */
+       case BTC_SET_BL_BT_DISABLE:
+               btcoexist->bt_info.bt_disabled = *bool_tmp;
+               break;
+       case BTC_SET_BL_BT_TRAFFIC_BUSY:
+               btcoexist->bt_info.bt_busy = *bool_tmp;
+               break;
+       case BTC_SET_BL_BT_LIMITED_DIG:
+               btcoexist->bt_info.limited_dig = *bool_tmp;
+               break;
+       case BTC_SET_BL_FORCE_TO_ROAM:
+               btcoexist->bt_info.force_to_roam = *bool_tmp;
+               break;
+       case BTC_SET_BL_TO_REJ_AP_AGG_PKT:
+               btcoexist->bt_info.reject_agg_pkt = *bool_tmp;
+               break;
+       case BTC_SET_BL_BT_CTRL_AGG_SIZE:
+               btcoexist->bt_info.b_bt_ctrl_buf_size = *bool_tmp;
+               break;
+       case BTC_SET_BL_INC_SCAN_DEV_NUM:
+               btcoexist->bt_info.increase_scan_dev_num = *bool_tmp;
+               break;
+               /* set some u1Byte type variables. */
+       case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON:
+               btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp;
+               break;
+       case BTC_SET_U1_AGG_BUF_SIZE:
+               btcoexist->bt_info.agg_buf_size = *u8_tmp;
+               break;
+               /* the following are some action which will be triggered */
+       case BTC_SET_ACT_GET_BT_RSSI:
+               /*BTHCI_SendGetBtRssiEvent(rtlpriv);*/
+               break;
+       case BTC_SET_ACT_AGGREGATE_CTRL:
+               halbtc_aggregation_check();
+               break;
+
+               /* 1Ant */
+       case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE:
+               btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp;
+               break;
+       case BTC_SET_UI_SCAN_SIG_COMPENSATION:
+       /*      rtlpriv->mlmepriv.scan_compensation = *u8_tmp;  */
+               break;
+       case BTC_SET_U1_1ANT_LPS:
+               btcoexist->bt_info.lps_1ant = *u8_tmp;
+               break;
+       case BTC_SET_U1_1ANT_RPWM:
+               btcoexist->bt_info.rpwm_1ant = *u8_tmp;
+               break;
+       /* the following are some action which will be triggered  */
+       case BTC_SET_ACT_LEAVE_LPS:
+               halbtc_leave_lps(btcoexist);
+               break;
+       case BTC_SET_ACT_ENTER_LPS:
+               halbtc_enter_lps(btcoexist);
+               break;
+       case BTC_SET_ACT_NORMAL_LPS:
+               halbtc_normal_lps(btcoexist);
+               break;
+       case BTC_SET_ACT_DISABLE_LOW_POWER:
+               halbtc_disable_low_power();
+               break;
+       case BTC_SET_ACT_UPDATE_ra_mask:
+               btcoexist->bt_info.ra_mask = *u32_tmp;
+               break;
+       case BTC_SET_ACT_SEND_MIMO_PS:
+               break;
+       case BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT:
+               btcoexist->bt_info.force_exec_pwr_cmd_cnt++;
+               break;
+       case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/
+               break;
+       case BTC_SET_ACT_CTRL_BT_COEX:
+               break;
+       default:
+               break;
+       }
+       
+       return true;
+}
+
+void halbtc_display_coex_statistics(struct btc_coexist *btcoexist)
+{
+}
+
+void halbtc_display_bt_link_info(struct btc_coexist *btcoexist)
+{
+}
+
+void halbtc_display_bt_fw_info(struct btc_coexist *btcoexist)
+{
+}
+
+void halbtc_display_fw_pwr_mode_cmd(struct btc_coexist *btcoexist)
+{
+}
+
+/************************************************************
+ *             IO related function
+ ************************************************************/
+u8 halbtc_read_1byte(void *bt_context, u32 reg_addr)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       
+       return  rtl_read_byte(rtlpriv, reg_addr);
+}
+
+
+u16 halbtc_read_2byte(void *bt_context, u32 reg_addr)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       return  rtl_read_word(rtlpriv, reg_addr);
+}
+
+
+u32 halbtc_read_4byte(void *bt_context, u32 reg_addr)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       
+       return  rtl_read_dword(rtlpriv, reg_addr);
+}
+
+
+void halbtc_write_1byte(void *bt_context, u32 reg_addr, u8 data)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       rtl_write_byte(rtlpriv, reg_addr, data);
+}
+
+void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr, 
+                               u8 bit_mask, u8 data)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       u8 original_value, bit_shift = 0;
+       u8 i;
+
+       if (bit_mask != MASKDWORD) {/*if not "double word" write*/
+               original_value = rtl_read_byte(rtlpriv, reg_addr);      
+               for (i=0; i<=7; i++) {
+                       if((bit_mask>>i)&0x1)
+                               break;
+               }
+               bit_shift = i;
+               data = (original_value & (~bit_mask)) | 
+                       ((data << bit_shift) & bit_mask);
+       }
+       rtl_write_byte(rtlpriv, reg_addr, data);
+}
+
+
+void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       rtl_write_word(rtlpriv, reg_addr, data);
+}
+
+
+void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data)
+{
+       struct btc_coexist *btcoexist = 
+               (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       rtl_write_dword(rtlpriv, reg_addr, data);
+}
+
+
+void halbtc_set_macreg(void *bt_context, u32 reg_addr, u32 bit_mask, u32 data)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
+}
+
+
+u32 halbtc_get_macreg(void *bt_context, u32 reg_addr, u32 bit_mask)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
+}
+
+
+void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask, u32 data)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
+}
+
+
+u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       return rtl_get_bbreg(rtlpriv->mac80211.hw,reg_addr, bit_mask);
+}
+
+
+void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr, 
+                     u32 bit_mask, u32 data)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data);
+}
+
+
+u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr, u32 bit_mask)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+
+       return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask);
+}
+
+
+void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id, 
+                        u32 cmd_len, u8 *cmd_buf)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       
+       rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id, 
+                                       cmd_len, cmd_buf);
+}
+
+void halbtc_display_dbg_msg(void *bt_context, u8 disp_type)
+{
+       struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
+       switch (disp_type) {
+       case BTC_DBG_DISP_COEX_STATISTICS:
+               halbtc_display_coex_statistics(btcoexist);
+               break;
+       case BTC_DBG_DISP_BT_LINK_INFO:
+               halbtc_display_bt_link_info(btcoexist);
+               break;
+       case BTC_DBG_DISP_BT_FW_VER:
+               halbtc_display_bt_fw_info(btcoexist);
+               break;
+       case BTC_DBG_DISP_FW_PWR_MODE_CMD:
+               halbtc_display_fw_pwr_mode_cmd(btcoexist);
+               break;
+       default:
+               break;
+       }
+}
+
+bool halbtc_under_ips(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
+       enum rf_pwrstate rtstate;
+       
+       if (ppsc->b_inactiveps) {
+               rtstate = ppsc->rfpwr_state;
+
+               if (rtstate != ERFON &&
+                   ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
+
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+/*****************************************************************
+ *         Extern functions called by other module
+ *****************************************************************/
+bool exhalbtc_initlize_variables(struct rtl_priv *adapter)
+{
+       struct btc_coexist *btcoexist = &gl_bt_coexist;
+
+       btcoexist->statistics.cnt_bind++;
+       
+       halbtc_dbg_init();
+
+       if (btcoexist->binded)
+               return false;
+       else
+               btcoexist->binded = true;
+
+#if ( defined(CONFIG_PCI_HCI))
+       btcoexist->chip_interface = BTC_INTF_PCI;
+#elif ( defined(CONFIG_USB_HCI))
+       btcoexist->chip_interface = BTC_INTF_USB;
+#elif ( defined(CONFIG_SDIO_HCI))
+       btcoexist->chip_interface = BTC_INTF_SDIO;
+#elif ( defined(CONFIG_GSPI_HCI))
+       btcoexist->chip_interface = BTC_INTF_GSPI;
+#else
+       btcoexist->chip_interface = BTC_INTF_UNKNOWN;
+#endif
+
+       if (NULL == btcoexist->adapter)
+               btcoexist->adapter = adapter;
+
+       btcoexist->stack_info.profile_notified = false;
+
+       btcoexist->btc_read_1byte = halbtc_read_1byte;
+       btcoexist->btc_write_1byte = halbtc_write_1byte;
+       btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte;
+       btcoexist->btc_read_2byte = halbtc_read_2byte;
+       btcoexist->btc_write_2byte = halbtc_write_2byte;
+       btcoexist->btc_read_4byte = halbtc_read_4byte;
+       btcoexist->btc_write_4byte = halbtc_write_4byte;
+
+       btcoexist->btc_set_bb_reg = halbtc_set_bbreg;
+       btcoexist->btc_get_bb_reg = halbtc_get_bbreg;
+
+       btcoexist->btc_set_rf_reg = halbtc_set_rfreg;
+       btcoexist->btc_get_rf_reg = halbtc_get_rfreg;
+
+       btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd;
+       btcoexist->btc_disp_dbg_msg = halbtc_display_dbg_msg;
+       
+       btcoexist->btc_get = halbtc_get;
+       btcoexist->btc_set = halbtc_set;
+
+       btcoexist->cli_buf = &btc_dbg_buf[0];
+
+       btcoexist->bt_info.b_bt_ctrl_buf_size = false;
+       btcoexist->bt_info.agg_buf_size = 5;
+
+       btcoexist->bt_info.increase_scan_dev_num = false;
+       return true;
+}
+
+void exhalbtc_init_hw_config(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+
+       btcoexist->statistics.cnt_init_hw_config++;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_init_hwconfig(btcoexist);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_init_hwconfig(btcoexist);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_init_hwconfig(btcoexist);
+       }
+       
+}
+
+void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+
+       btcoexist->statistics.cnt_init_coex_dm++;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_init_coex_dm(btcoexist);             
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_init_coex_dm(btcoexist);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_init_coex_dm(btcoexist);
+       }
+       
+       btcoexist->initilized = true;
+}
+
+void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u8 ips_type;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_ips_notify++;
+       if (btcoexist->manual_control)
+               return;
+
+       if (ERFOFF == type)
+               ips_type = BTC_IPS_ENTER;
+       else
+               ips_type = BTC_IPS_LEAVE;
+
+       halbtc_leave_low_power();
+       
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_ips_notify(btcoexist, ips_type);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_ips_notify(btcoexist, ips_type);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_ips_notify(btcoexist, ips_type);
+       }
+
+       halbtc_nomal_low_power();
+}
+
+void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u8 lps_type;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_lps_notify++;
+       if (btcoexist->manual_control)
+               return;
+       
+       if (EACTIVE == type)
+               lps_type = BTC_LPS_DISABLE;
+       else
+               lps_type = BTC_LPS_ENABLE;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_lps_notify(btcoexist, lps_type);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_lps_notify(btcoexist, lps_type);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_lps_notify(btcoexist, lps_type);
+       }
+}
+
+void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u8 scan_type;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_scan_notify++;
+       if (btcoexist->manual_control)
+               return;
+
+       if (type)
+               scan_type = BTC_SCAN_START;
+       else
+               scan_type = BTC_SCAN_FINISH;
+
+       halbtc_leave_low_power();
+       
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_scan_notify(btcoexist, scan_type);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_scan_notify(btcoexist, scan_type);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_scan_notify(btcoexist, scan_type);
+       }
+
+       halbtc_nomal_low_power();
+}
+
+void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u8 asso_type;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_connect_notify++;
+       if (btcoexist->manual_control)
+               return;
+
+       if (action)
+               asso_type = BTC_ASSOCIATE_START;
+       else
+               asso_type = BTC_ASSOCIATE_FINISH;
+
+       halbtc_leave_low_power();
+       
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_connect_notify(btcoexist, asso_type);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_connect_notify(btcoexist, asso_type);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_connect_notify(btcoexist, asso_type);
+       }
+
+       halbtc_nomal_low_power();
+}
+
+void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, 
+                                enum rt_media_status media_status)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u8 status;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_media_status_notify++;
+       if (btcoexist->manual_control)
+               return;
+
+       if (RT_MEDIA_CONNECT == media_status)
+               status = BTC_MEDIA_CONNECT;
+       else
+               status = BTC_MEDIA_DISCONNECT;
+
+       halbtc_leave_low_power();
+       
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_media_status_notify(btcoexist, status);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_media_status_notify(btcoexist, status);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_media_status_notify(btcoexist, status);
+       }
+
+       halbtc_nomal_low_power();
+}
+
+void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type)
+{
+       u8 packet_type;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_special_packet_notify++;
+       if (btcoexist->manual_control)
+               return;
+
+       /*if(PACKET_DHCP == pkt_type)*/
+               packet_type = BTC_PACKET_DHCP;
+       /*else if(PACKET_EAPOL == pkt_type)
+               packet_type = BTC_PACKET_EAPOL;
+       else
+               packet_type = BTC_PACKET_UNKNOWN;*/
+
+       halbtc_leave_low_power();
+
+       if (btcoexist->board_info.btdm_ant_num == 2)
+               ex_halbtc8723b2ant_special_packet_notify(btcoexist,
+                                                        packet_type);
+       else if (btcoexist->board_info.btdm_ant_num == 1)
+               ex_halbtc8723b1ant_special_packet_notify(btcoexist,
+                                                        packet_type);
+
+       halbtc_nomal_low_power();
+}
+
+void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, 
+                            u8 *tmp_buf, u8 length)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_bt_info_notify++;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_bt_info_notify(btcoexist, tmp_buf, length);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+       //      ex_halbtc8192e2ant_bt_info_notify(btcoexist, tmp_buf, length);
+       }
+}
+
+void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type)
+{
+       u8 stack_op_type;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_stack_operation_notify++;
+       if (btcoexist->manual_control)
+               return;
+
+       stack_op_type = BTC_STACK_OP_NONE;
+}
+
+void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_halt_notify(btcoexist);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_halt_notify(btcoexist);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_halt_notify(btcoexist);
+       }
+}
+
+void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
+{
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+}
+
+void exhalbtc_periodical(struct btc_coexist *btcoexist)
+{
+       struct rtl_priv *rtlpriv = btcoexist->adapter;
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_periodical++;
+
+       halbtc_leave_low_power();
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (btcoexist->board_info.btdm_ant_num == 2)
+                       ex_halbtc8723b2ant_periodical(btcoexist);
+               else if(btcoexist->board_info.btdm_ant_num == 1)
+                       ex_halbtc8723b1ant_periodical(btcoexist);
+       } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE) {
+               ex_halbtc8192e2ant_periodical(btcoexist);
+       }
+
+       halbtc_nomal_low_power();
+}
+
+void exhalbtc_dbg_control(struct btc_coexist *btcoexist, 
+                         u8 code, u8 len, u8 *data)
+{
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       btcoexist->statistics.cnt_dbg_ctrl++;
+}
+
+void exhalbtc_stack_update_profile_info()
+{
+}
+
+void exhalbtc_update_min_bt_rssi(char bt_rssi)
+{
+       struct btc_coexist *btcoexist = &gl_bt_coexist;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+
+       btcoexist->stack_info.min_bt_rssi = bt_rssi;
+}
+
+
+void exhalbtc_set_hci_version(u16 hci_version)
+{
+       struct btc_coexist *btcoexist = &gl_bt_coexist;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+
+       btcoexist->stack_info.hci_version = hci_version;
+}
+
+void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version) 
+{
+       struct btc_coexist *btcoexist = &gl_bt_coexist;
+
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+
+       btcoexist->bt_info.bt_real_fw_ver = bt_patch_version;
+       btcoexist->bt_info.bt_hci_ver = bt_hci_version;
+}
+
+void exhalbtc_set_bt_exist(bool bt_exist)
+{
+       gl_bt_coexist.board_info.bt_exist = bt_exist;
+}
+
+void exhalbtc_set_chip_type(u8 chip_type)
+{
+       switch (chip_type) {
+       default:
+       case BT_2WIRE:
+       case BT_ISSC_3WIRE:
+       case BT_ACCEL:
+       case BT_RTL8756:
+               gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_UNDEF;
+               break;
+       case BT_CSR_BC4:
+               gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC4;
+               break;
+       case BT_CSR_BC8:
+               gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC8;
+               break;
+       case BT_RTL8723A:
+               gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723A;
+               break;
+       case BT_RTL8821A:
+               gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8821;
+               break;
+       case BT_RTL8723B:
+               gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723B;
+               break;
+       }
+}
+
+void exhalbtc_set_ant_num(u8 type, u8 ant_num)
+{
+       if (BT_COEX_ANT_TYPE_PG == type) {
+               gl_bt_coexist.board_info.pg_ant_num = ant_num;
+               gl_bt_coexist.board_info.btdm_ant_num = ant_num;
+       } else if (BT_COEX_ANT_TYPE_ANTDIV == type) {
+               gl_bt_coexist.board_info.btdm_ant_num = ant_num;
+       }
+}
+
+void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist)
+{
+       if (!halbtc_is_bt_coexist_available(btcoexist))
+               return;
+       
+       if (btcoexist->board_info.btdm_ant_num == 2)
+               ex_halbtc8723b2ant_display_coex_info(btcoexist);
+       else if (btcoexist->board_info.btdm_ant_num == 1)
+               ex_halbtc8723b1ant_display_coex_info(btcoexist);
+}
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h b/drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h
new file mode 100644 (file)
index 0000000..787798e
--- /dev/null
@@ -0,0 +1,549 @@
+#ifndef        __HALBTC_OUT_SRC_H__
+#define __HALBTC_OUT_SRC_H__
+
+#include       "../wifi.h"
+
+#define                NORMAL_EXEC                             false
+#define                FORCE_EXEC                              true
+
+#define                BTC_RF_A                                RF90_PATH_A
+#define                BTC_RF_B                                RF90_PATH_B
+#define                BTC_RF_C                                RF90_PATH_C
+#define                BTC_RF_D                                RF90_PATH_D
+
+#define                BTC_SMSP                                SINGLEMAC_SINGLEPHY
+#define                BTC_DMDP                                DUALMAC_DUALPHY
+#define                BTC_DMSP                                DUALMAC_SINGLEPHY
+#define                BTC_MP_UNKNOWN                          0xff
+
+#define        IN
+#define        OUT
+
+#define        BT_TMP_BUF_SIZE                         100
+
+#define                BT_COEX_ANT_TYPE_PG                     0
+#define                BT_COEX_ANT_TYPE_ANTDIV                 1
+#define                BT_COEX_ANT_TYPE_DETECTED               2
+
+#define                BTC_MIMO_PS_STATIC                      0
+#define                BTC_MIMO_PS_DYNAMIC                     1
+
+#define                BTC_RATE_DISABLE                        0
+#define                BTC_RATE_ENABLE                         1
+
+/* single Antenna definition */
+#define                BTC_ANT_PATH_WIFI                       0
+#define                BTC_ANT_PATH_BT                         1
+#define                BTC_ANT_PATH_PTA                        2
+/* dual Antenna definition */
+#define                BTC_ANT_WIFI_AT_MAIN                    0
+#define                BTC_ANT_WIFI_AT_AUX                     1
+/* coupler Antenna definition */
+#define                BTC_ANT_WIFI_AT_CPL_MAIN                0
+#define                BTC_ANT_WIFI_AT_CPL_AUX                 1
+
+enum btc_chip_interface{
+       BTC_INTF_UNKNOWN        = 0,
+       BTC_INTF_PCI            = 1,
+       BTC_INTF_USB            = 2,
+       BTC_INTF_SDIO           = 3,
+       BTC_INTF_GSPI           = 4,
+       BTC_INTF_MAX
+};
+
+enum btc_chip_type{
+       BTC_CHIP_UNDEF          = 0,
+       BTC_CHIP_CSR_BC4        = 1,
+       BTC_CHIP_CSR_BC8        = 2,
+       BTC_CHIP_RTL8723A       = 3,
+       BTC_CHIP_RTL8821        = 4,
+       BTC_CHIP_RTL8723B       = 5,
+       BTC_CHIP_MAX
+};
+
+enum btc_msg_type{
+       BTC_MSG_INTERFACE       = 0x0,
+       BTC_MSG_ALGORITHM       = 0x1,
+       BTC_MSG_MAX
+};
+
+extern u32 btc_dbg_type[];
+
+/* following is for BTC_MSG_INTERFACE */
+#define                INTF_INIT                               BIT0
+#define                INTF_NOTIFY                             BIT2
+
+/* following is for BTC_ALGORITHM */
+#define                ALGO_BT_RSSI_STATE                      BIT0
+#define                ALGO_WIFI_RSSI_STATE                    BIT1
+#define                ALGO_BT_MONITOR                         BIT2
+#define                ALGO_TRACE                              BIT3
+#define                ALGO_TRACE_FW                           BIT4
+#define                ALGO_TRACE_FW_DETAIL                    BIT5
+#define                ALGO_TRACE_FW_EXEC                      BIT6
+#define                ALGO_TRACE_SW                           BIT7
+#define                ALGO_TRACE_SW_DETAIL                    BIT8
+#define                ALGO_TRACE_SW_EXEC                      BIT9
+
+
+
+#define        CL_SPRINTF      snprintf
+#define        CL_PRINTF       printk
+
+#define        BTC_PRINT(dbgtype, dbgflag, printstr, ...)              \
+       do {                                                    \
+               if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\
+                       printk(printstr, ##__VA_ARGS__);        \
+               }                                               \
+       } while(0)
+
+#define        BTC_PRINT_F(dbgtype, dbgflag, printstr, ...)            \
+       do {                                                    \
+               if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\
+                       printk(KERN_DEBUG "%s: ", __func__);    \
+                       printk(printstr, ##__VA_ARGS__);        \
+               }                                               \
+       } while(0)
+
+#define        BTC_PRINT_ADDR(dbgtype, dbgflag, printstr, _ptr)        \
+       do {                                                    \
+               if(unlikely(btc_dbg_type[dbgtype] & dbgflag)) { \
+                       int __i;                                \
+                       u8* __ptr = (u8*)_Ptr;                  \
+                       printk printstr;                        \
+                       for( __i = 0; __i < 6; __i++ )          \
+                               printk("%02X%s", __ptr[__i], (__i==5)?"":"-");\
+                       printk(KERN_DEBUG "\n");                \
+               }\
+       } while(0)
+
+#define BTC_PRINT_DATA(dbgtype, dbgflag, _titlestring, _hexdata, _hexdatalen) \
+       do {                                                            \
+               if(unlikely(btc_dbg_type[dbgtype] & dbgflag) )  {       \
+                       int __i;                                        \
+                       u8 *__ptr = (u8*)_hexdata;                      \
+                       printk(_titlestring);                           \
+                       for( __i = 0; __i < (int)_hexdatalen; __i++ ) { \
+                               printk("%02X%s", __ptr[__i], (((__i + 1) % 4) \
+                                                       == 0)?"  ":" ");\
+                               if (((__i + 1) % 16) == 0)              \
+                                       printk("\n");                   \
+                       }                                               \
+                       printk(KERN_DEBUG "\n");                        \
+               }                                                       \
+       } while(0)
+
+
+#define        BTC_RSSI_HIGH(_rssi_) \
+       ((_rssi_==BTC_RSSI_STATE_HIGH || _rssi_==BTC_RSSI_STATE_STAY_HIGH) ? \
+       true : false)
+
+#define        BTC_RSSI_MEDIUM(_rssi_) \
+       ((_rssi_==BTC_RSSI_STATE_MEDIUM || _rssi_==BTC_RSSI_STATE_STAY_MEDIUM) \
+       ? true : false)
+
+#define        BTC_RSSI_LOW(_rssi_) \
+       ((_rssi_==BTC_RSSI_STATE_LOW || _rssi_==BTC_RSSI_STATE_STAY_LOW) ? \
+       true : false)
+
+
+enum btc_power_save_type {
+       BTC_PS_WIFI_NATIVE = 0,
+       BTC_PS_LPS_ON = 1,
+       BTC_PS_LPS_OFF = 2,
+       BTC_PS_LPS_MAX
+};
+
+struct btc_board_info {
+       /* The following is some board information */
+       u8 bt_chip_type;
+       u8 pg_ant_num;  /* pg ant number */
+       u8 btdm_ant_num;        /* ant number for btdm */
+       u8 btdm_ant_pos;
+       bool bt_exist;
+};
+
+enum btc_dbg_opcode{
+       BTC_DBG_SET_COEX_NORMAL = 0x0,
+       BTC_DBG_SET_COEX_WIFI_ONLY = 0x1,
+       BTC_DBG_SET_COEX_BT_ONLY = 0x2,
+       BTC_DBG_MAX
+};
+
+enum btc_rssi_state{
+       BTC_RSSI_STATE_HIGH = 0x0,
+       BTC_RSSI_STATE_MEDIUM = 0x1,
+       BTC_RSSI_STATE_LOW = 0x2,
+       BTC_RSSI_STATE_STAY_HIGH = 0x3,
+       BTC_RSSI_STATE_STAY_MEDIUM = 0x4,
+       BTC_RSSI_STATE_STAY_LOW = 0x5,
+       BTC_RSSI_MAX
+};
+
+enum btc_wifi_role{
+       BTC_ROLE_STATION = 0x0,
+       BTC_ROLE_AP = 0x1,
+       BTC_ROLE_IBSS = 0x2,
+       BTC_ROLE_HS_MODE = 0x3,
+       BTC_ROLE_MAX
+};
+
+enum btc_wifi_bw_mode{
+       BTC_WIFI_BW_LEGACY = 0x0,
+       BTC_WIFI_BW_HT20 = 0x1,
+       BTC_WIFI_BW_HT40 = 0x2,
+       BTC_WIFI_BW_MAX
+};
+
+enum btc_wifi_traffic_dir{
+       BTC_WIFI_TRAFFIC_TX = 0x0,
+       BTC_WIFI_TRAFFIC_RX = 0x1,
+       BTC_WIFI_TRAFFIC_MAX
+};
+
+enum btc_wifi_pnp{
+       BTC_WIFI_PNP_WAKE_UP = 0x0,
+       BTC_WIFI_PNP_SLEEP = 0x1,
+       BTC_WIFI_PNP_MAX
+};
+
+
+enum btc_get_type{
+       /* type bool */
+       BTC_GET_BL_HS_OPERATION,
+       BTC_GET_BL_HS_CONNECTING,
+       BTC_GET_BL_WIFI_CONNECTED,
+       BTC_GET_BL_WIFI_BUSY,
+       BTC_GET_BL_WIFI_SCAN,
+       BTC_GET_BL_WIFI_LINK,
+       BTC_GET_BL_WIFI_DHCP,
+       BTC_GET_BL_WIFI_SOFTAP_IDLE,
+       BTC_GET_BL_WIFI_SOFTAP_LINKING,
+       BTC_GET_BL_WIFI_IN_EARLY_SUSPEND,
+       BTC_GET_BL_WIFI_ROAM,
+       BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+       BTC_GET_BL_WIFI_UNDER_5G,
+       BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+       BTC_GET_BL_WIFI_ENABLE_ENCRYPTION,
+       BTC_GET_BL_WIFI_UNDER_B_MODE,
+       BTC_GET_BL_EXT_SWITCH,
+
+       /* type s4Byte */
+       BTC_GET_S4_WIFI_RSSI,
+       BTC_GET_S4_HS_RSSI,
+
+       /* type u32 */
+       BTC_GET_U4_WIFI_BW,
+       BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
+       BTC_GET_U4_WIFI_FW_VER,
+       BTC_GET_U4_BT_PATCH_VER,
+
+       /* type u1Byte */
+       BTC_GET_U1_WIFI_DOT11_CHNL,
+       BTC_GET_U1_WIFI_CENTRAL_CHNL,
+       BTC_GET_U1_WIFI_HS_CHNL,
+       BTC_GET_U1_MAC_PHY_MODE,
+       BTC_GET_U1_AP_NUM,
+
+       /* for 1Ant */
+       BTC_GET_U1_LPS_MODE,
+       BTC_GET_BL_BT_SCO_BUSY,
+
+       /* for test mode */
+       BTC_GET_DRIVER_TEST_CFG,
+#if 0
+       BTC_GET_U1_LPS,
+       BTC_GET_U1_RPWM,
+#endif
+       BTC_GET_MAX
+};
+
+
+enum btc_set_type{
+       /* type bool */
+       BTC_SET_BL_BT_DISABLE,
+       BTC_SET_BL_BT_TRAFFIC_BUSY,
+       BTC_SET_BL_BT_LIMITED_DIG,
+       BTC_SET_BL_FORCE_TO_ROAM,
+       BTC_SET_BL_TO_REJ_AP_AGG_PKT,
+       BTC_SET_BL_BT_CTRL_AGG_SIZE,
+       BTC_SET_BL_INC_SCAN_DEV_NUM,
+
+       /* type u1Byte */
+       BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON,
+       BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE,
+       BTC_SET_UI_SCAN_SIG_COMPENSATION,
+       BTC_SET_U1_AGG_BUF_SIZE,
+
+       /* type trigger some action */
+       BTC_SET_ACT_GET_BT_RSSI,
+       BTC_SET_ACT_AGGREGATE_CTRL,
+
+       /********* for 1Ant **********/
+       /* type bool */
+       BTC_SET_BL_BT_SCO_BUSY,
+       /* type u1Byte */
+       BTC_SET_U1_1ANT_LPS,
+       BTC_SET_U1_1ANT_RPWM,
+       /* type trigger some action */
+       BTC_SET_ACT_LEAVE_LPS,
+       BTC_SET_ACT_ENTER_LPS,
+       BTC_SET_ACT_NORMAL_LPS,
+       BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT,
+       BTC_SET_ACT_DISABLE_LOW_POWER,
+       BTC_SET_ACT_UPDATE_ra_mask,
+       BTC_SET_ACT_SEND_MIMO_PS,
+       /* BT Coex related */
+       BTC_SET_ACT_CTRL_BT_INFO,
+       BTC_SET_ACT_CTRL_BT_COEX,
+       /***************************/
+       BTC_SET_MAX
+};
+
+enum btc_dbg_disp_type{
+       BTC_DBG_DISP_COEX_STATISTICS = 0x0,
+       BTC_DBG_DISP_BT_LINK_INFO = 0x1,
+       BTC_DBG_DISP_BT_FW_VER = 0x2,
+       BTC_DBG_DISP_FW_PWR_MODE_CMD = 0x3,
+       BTC_DBG_DISP_MAX
+};
+
+enum btc_notify_type_ips{
+       BTC_IPS_LEAVE = 0x0,
+       BTC_IPS_ENTER = 0x1,
+       BTC_IPS_MAX
+};
+
+enum btc_notify_type_lps{
+       BTC_LPS_DISABLE = 0x0,
+       BTC_LPS_ENABLE = 0x1,
+       BTC_LPS_MAX
+};
+
+enum btc_notify_type_scan{
+       BTC_SCAN_FINISH = 0x0,
+       BTC_SCAN_START = 0x1,
+       BTC_SCAN_MAX
+};
+
+enum btc_notify_type_associate{
+       BTC_ASSOCIATE_FINISH = 0x0,
+       BTC_ASSOCIATE_START = 0x1,
+       BTC_ASSOCIATE_MAX
+};
+
+enum btc_notify_type_media_status{
+       BTC_MEDIA_DISCONNECT = 0x0,
+       BTC_MEDIA_CONNECT = 0x1,
+       BTC_MEDIA_MAX
+};
+
+enum btc_notify_type_special_packet{
+       BTC_PACKET_UNKNOWN = 0x0,
+       BTC_PACKET_DHCP = 0x1,
+       BTC_PACKET_ARP = 0x2,
+       BTC_PACKET_EAPOL = 0x3,
+       BTC_PACKET_MAX
+};
+
+enum btc_notify_type_stack_operation{
+       BTC_STACK_OP_NONE = 0x0,
+       BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1,
+       BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2,
+       BTC_STACK_OP_MAX
+};
+
+
+typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr);
+
+typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr);
+
+typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr);
+
+typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u8 data);
+
+typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr,
+                                  u8 bit_mask, u8 data1b);
+
+typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data);
+
+typedef void (*bfp_btc_w4)(void *btc_context, u32 reg_addr, u32 data);
+
+typedef void (*bfp_btc_wr_1byte_bit_mask)(void *btc_context, u32 reg_addr,
+                                         u8 bit_mask, u8 data);
+
+typedef void (*bfp_btc_set_bb_reg)(void *btc_context, u32 reg_addr,
+                                  u32 bit_mask, u32 data);
+
+typedef u32 (*bfp_btc_get_bb_reg)(void *btc_context, u32 reg_addr,
+                                 u32 bit_mask);
+
+typedef void (*bfp_btc_set_rf_reg)(void *btc_context, u8 rf_path, u32 reg_addr,
+                                  u32 bit_mask, u32 data);
+
+typedef u32 (*bfp_btc_get_rf_reg)(void *btc_context, u8 rf_path,
+                                 u32 reg_addr, u32 bit_mask);
+
+typedef void (*bfp_btc_fill_h2c)(void *btc_context, u8 element_id,
+                                u32 cmd_len, u8 *cmd_buffer);
+
+typedef        bool (*bfp_btc_get)(void *btcoexist, u8 get_type, void *out_buf);
+
+typedef        bool (*bfp_btc_set)(void *btcoexist, u8 set_type, void *in_buf);
+
+typedef void (*bfp_btc_disp_dbg_msg)(void *btcoexist, u8 disp_type);
+
+struct btc_bt_info {
+       bool bt_disabled;
+       u8 rssi_adjust_for_agc_table_on;
+       u8 rssi_adjust_for_1ant_coex_type;
+       bool bt_busy;
+       u8 agg_buf_size;
+       bool limited_dig;
+       bool reject_agg_pkt;
+       bool b_bt_ctrl_buf_size;
+       bool increase_scan_dev_num;
+       u16 bt_hci_ver;
+       u16 bt_real_fw_ver;
+       u8 bt_fw_ver;
+
+       /* the following is for 1Ant solution */
+       bool bt_ctrl_lps;
+       bool bt_pwr_save_mode;
+       bool bt_lps_on;
+       bool force_to_roam;
+       u8 force_exec_pwr_cmd_cnt;
+       u8 lps_1ant;
+       u8 rpwm_1ant;
+       u32 ra_mask;
+};
+
+struct btc_stack_info {
+       bool profile_notified;
+       u16 hci_version;        /* stack hci version */
+       u8 num_of_link;
+       bool bt_link_exist;
+       bool sco_exist;
+       bool acl_exist;
+       bool a2dp_exist;
+       bool hid_exist;
+       u8 num_of_hid;
+       bool pan_exist;
+       bool unknown_acl_exist;
+       char min_bt_rssi;
+};
+
+struct btc_statistics {
+       u32 cnt_bind;
+       u32 cnt_init_hw_config;
+       u32 cnt_init_coex_dm;
+       u32 cnt_ips_notify;
+       u32 cnt_lps_notify;
+       u32 cnt_scan_notify;
+       u32 cnt_connect_notify;
+       u32 cnt_media_status_notify;
+       u32 cnt_special_packet_notify;
+       u32 cnt_bt_info_notify;
+       u32 cnt_periodical;
+       u32 cnt_stack_operation_notify;
+       u32 cnt_dbg_ctrl;
+};
+
+struct btc_bt_link_info {
+       bool bt_link_exist;
+       bool sco_exist;
+       bool sco_only;
+       bool a2dp_exist;
+       bool a2dp_only;
+       bool hid_exist;
+       bool hid_only;
+       bool pan_exist;
+       bool pan_only;
+};
+
+enum btc_antenna_pos {
+       BTC_ANTENNA_AT_MAIN_PORT = 0x1,
+       BTC_ANTENNA_AT_AUX_PORT = 0x2,
+};
+
+struct btc_coexist {
+       /* make sure only one adapter can bind the data context  */
+       bool binded;
+       /* default adapter */
+       void *adapter;
+       struct btc_board_info board_info;
+       /* some bt info referenced by non-bt module */
+       struct btc_bt_info bt_info;
+       struct btc_stack_info stack_info;
+       enum btc_chip_interface chip_interface;
+       struct btc_bt_link_info bt_link_info;
+
+       bool initilized;
+       bool stop_coex_dm;
+       bool manual_control;
+       u8 *cli_buf;
+       struct btc_statistics statistics;
+       u8 pwr_mode_val[10];
+
+       /* function pointers
+        * io related */
+       bfp_btc_r1 btc_read_1byte;
+       bfp_btc_w1 btc_write_1byte;
+       bfp_btc_w1_bit_mak btc_write_1byte_bitmask;
+       bfp_btc_r2 btc_read_2byte;
+       bfp_btc_w2 btc_write_2byte;
+       bfp_btc_r4 btc_read_4byte;
+       bfp_btc_w4 btc_write_4byte;
+
+       bfp_btc_set_bb_reg btc_set_bb_reg;
+       bfp_btc_get_bb_reg btc_get_bb_reg;
+
+
+       bfp_btc_set_rf_reg btc_set_rf_reg;
+       bfp_btc_get_rf_reg btc_get_rf_reg;
+
+
+       bfp_btc_fill_h2c btc_fill_h2c;
+
+       bfp_btc_disp_dbg_msg btc_disp_dbg_msg;
+
+       bfp_btc_get btc_get;
+       bfp_btc_set btc_set;
+};
+
+bool halbtc_is_wifi_uplink(struct rtl_priv *adapter);
+
+
+extern struct btc_coexist gl_bt_coexist;
+
+bool exhalbtc_initlize_variables(struct rtl_priv* adapter);
+void exhalbtc_init_hw_config(struct btc_coexist *btcoexist);
+void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist);
+void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action);
+void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
+                                enum rt_media_status media_status);
+void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type);
+void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
+                            u8 length);
+void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type);
+void exhalbtc_halt_notify(struct btc_coexist *btcoexist);
+void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
+void exhalbtc_periodical(struct btc_coexist *btcoexist);
+void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len,
+                         u8 *data);
+void exhalbtc_stack_update_profile_info(void);
+void exhalbtc_set_hci_version(u16 hci_version);
+void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version);
+void exhalbtc_update_min_bt_rssi(char bt_rssi);
+void exhalbtc_set_bt_exist(bool bt_exist);
+void exhalbtc_set_chip_type(u8 chip_type);
+void exhalbtc_set_ant_num(u8 type, u8 ant_num);
+void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist);
+void exhalbtc_signal_compensation(struct btc_coexist *btcoexist,
+                                 u8 *rssi_wifi, u8 *rssi_bt);
+void exhalbtc_lps_leave(struct btc_coexist *btcoexist);
+void exhalbtc_low_wifi_traffic_notify(struct btc_coexist *btcoexist);
+#endif
diff --git a/drivers/staging/rtl8821ae/btcoexist/rtl_btc.c b/drivers/staging/rtl8821ae/btcoexist/rtl_btc.c
new file mode 100644 (file)
index 0000000..6653f14
--- /dev/null
@@ -0,0 +1,236 @@
+/******************************************************************************
+ *
+ * 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/vmalloc.h>
+#include <linux/module.h>
+
+#include "rtl_btc.h"
+#include "halbt_precomp.h"
+
+struct rtl_btc_ops rtl_btc_operation ={
+       .btc_init_variables = rtl_btc_init_variables,
+       .btc_init_hal_vars = rtl_btc_init_hal_vars,
+       .btc_init_hw_config = rtl_btc_init_hw_config,
+       .btc_ips_notify = rtl_btc_ips_notify,
+       .btc_scan_notify = rtl_btc_scan_notify,
+       .btc_connect_notify = rtl_btc_connect_notify,
+       .btc_mediastatus_notify = rtl_btc_mediastatus_notify,
+       .btc_periodical = rtl_btc_periodical,
+       .btc_halt_notify = rtl_btc_halt_notify,
+       .btc_btinfo_notify = rtl_btc_btinfo_notify,
+       .btc_is_limited_dig = rtl_btc_is_limited_dig,
+       .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo,
+       .btc_is_bt_disabled = rtl_btc_is_bt_disabled,
+};
+
+
+void rtl_btc_init_variables(struct rtl_priv *rtlpriv)
+{
+
+       exhalbtc_initlize_variables(rtlpriv);
+}
+
+void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv)
+{
+       u8 ant_num;
+       u8 bt_exist;
+       u8 bt_type;
+       ant_num = rtl_get_hwpg_ant_num(rtlpriv);
+       RT_TRACE(COMP_INIT, DBG_DMESG, ("%s, antNum is %d\n", __func__, ant_num));
+
+       bt_exist = rtl_get_hwpg_bt_exist(rtlpriv);
+       RT_TRACE(COMP_INIT, DBG_DMESG, ("%s, bt_exist is %d\n", __func__, bt_exist));
+       exhalbtc_set_bt_exist(bt_exist);
+
+       bt_type = rtl_get_hwpg_bt_type(rtlpriv);
+       RT_TRACE(COMP_INIT, DBG_DMESG, ("%s, bt_type is %d\n", __func__, bt_type));
+       exhalbtc_set_chip_type(bt_type);
+
+       exhalbtc_set_ant_num(BT_COEX_ANT_TYPE_PG, ant_num);
+
+}
+
+
+void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv)
+{
+       exhalbtc_init_hw_config(&gl_bt_coexist);
+       exhalbtc_init_coex_dm(&gl_bt_coexist);
+}
+
+
+void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type)
+{
+       exhalbtc_ips_notify(&gl_bt_coexist, type);
+}
+
+
+void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype)
+{
+       exhalbtc_scan_notify(&gl_bt_coexist, scantype);
+}
+
+
+void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action)
+{
+       exhalbtc_connect_notify(&gl_bt_coexist, action);
+}
+
+
+void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, enum rt_media_status mstatus)
+{
+       exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus);
+}
+
+void rtl_btc_periodical(struct rtl_priv *rtlpriv)
+{
+//     rtl_bt_dm_monitor();
+       exhalbtc_periodical(&gl_bt_coexist);
+}
+
+void rtl_btc_halt_notify(void)
+{
+       exhalbtc_halt_notify(&gl_bt_coexist);
+}
+
+void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 * tmp_buf, u8 length)
+{
+       exhalbtc_bt_info_notify(&gl_bt_coexist, tmp_buf, length);
+}
+
+bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv)
+{
+       return gl_bt_coexist.bt_info.limited_dig;
+}
+
+bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv)
+{
+       bool bt_change_edca = false;
+       u32 cur_edca_val;
+       u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b;
+       u32 edca_hs;
+       u32 edca_addr = 0x504;
+
+       cur_edca_val = rtl_read_dword(rtlpriv, edca_addr);
+       if (halbtc_is_wifi_uplink(rtlpriv)){
+               if (cur_edca_val != edca_bt_hs_uplink){
+                       edca_hs = edca_bt_hs_uplink;
+                       bt_change_edca = true;
+               }
+       }else{
+               if (cur_edca_val != edca_bt_hs_downlink){
+                       edca_hs = edca_bt_hs_downlink;
+                       bt_change_edca = true;
+               }
+       }
+
+       if(bt_change_edca)
+               rtl_write_dword(rtlpriv, edca_addr, edca_hs);
+
+       return true;
+}
+
+bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv)
+{
+       if (gl_bt_coexist.bt_info.bt_disabled)
+               return true;
+       else
+               return false;
+}
+
+struct rtl_btc_ops *rtl_btc_get_ops_pointer(void)
+{
+       return &rtl_btc_operation;
+}
+//EXPORT_SYMBOL(rtl_btc_get_ops_pointer);
+
+u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
+{
+       u8 num;
+
+       if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2)
+               num = 2;
+       else
+               num = 1;
+
+       return num;
+}
+
+#if 0
+enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw)
+{
+    struct rtl_priv *rtlpriv = rtl_priv(hw);
+    struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+    enum rt_media_status    m_status = RT_MEDIA_DISCONNECT;
+
+    u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
+
+    if(bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
+            m_status = RT_MEDIA_CONNECT;
+    }
+
+    return m_status;
+}
+#endif
+
+u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv)
+{
+       return rtlpriv->btcoexist.btc_info.btcoexist;
+}
+
+u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
+{
+       return rtlpriv->btcoexist.btc_info.bt_type;
+}
+
+
+#if 0
+
+MODULE_AUTHOR("Page He <page_he@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");
+
+static int __init rtl_btcoexist_module_init(void)
+{
+
+       //printk("%s, rtlpriv->btc_ops.btc_init_variables addr is %p\n", __func__, rtlpriv->btc_ops.btc_init_variables);
+
+       return 0;
+}
+
+static void __exit rtl_btcoexist_module_exit(void)
+{
+       return;
+}
+
+module_init(rtl_btcoexist_module_init);
+module_exit(rtl_btcoexist_module_exit);
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/rtl_btc.h b/drivers/staging/rtl8821ae/btcoexist/rtl_btc.h
new file mode 100644 (file)
index 0000000..452fbf1
--- /dev/null
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ * 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_BTC_H__
+#define __RTL_BTC_H__
+
+#include "halbt_precomp.h"
+
+
+
+void rtl_btc_init_variables(struct rtl_priv *rtlpriv);
+void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv);
+void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv);
+void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type);
+void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype);
+void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action);
+void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, enum rt_media_status mstatus);
+void rtl_btc_periodical(struct rtl_priv *rtlpriv);
+void rtl_btc_halt_notify(void);
+void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 * tmpBuf, u8 length);
+bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv);
+bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv);
+bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv);
+
+
+//extern struct rtl_btc_ops rtl_btc_operation;
+extern struct rtl_btc_ops *rtl_btc_get_ops_pointer(void);
+
+u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv);
+u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv);
+u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv);
+//enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw);
+
+
+
+
+
+
+
+
+#endif
diff --git a/drivers/staging/rtl8821ae/cam.c b/drivers/staging/rtl8821ae/cam.c
new file mode 100644 (file)
index 0000000..72743e7
--- /dev/null
@@ -0,0 +1,354 @@
+/******************************************************************************
+ *
+ * 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 "wifi.h"
+#include "cam.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+#include <linux/export.h>
+#endif
+
+void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->sec.use_defaultkey = false;
+       rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION;
+       rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION;
+       memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN);
+       memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE);
+       rtlpriv->sec.pairwise_key = NULL;
+}
+
+static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
+                          u8 *mac_addr, u8 *key_cont_128, u16 us_config)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       u32 target_command;
+       u32 target_content = 0;
+       u8 entry_i;
+
+       RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_DMESG, "Key content :",
+                       key_cont_128, 16);
+
+       for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+               target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
+               target_command = target_command | BIT(31) | BIT(16);
+
+               if (entry_i == 0) {
+                       target_content = (u32) (*(mac_addr + 0)) << 16 |
+                           (u32) (*(mac_addr + 1)) << 24 | (u32) us_config;
+
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+                                       target_content);
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+                                       target_command);
+
+                       RT_TRACE(COMP_SEC, DBG_LOUD,
+                                ("WRITE %x: %x \n",
+                                 rtlpriv->cfg->maps[WCAMI], target_content));
+                       RT_TRACE(COMP_SEC, DBG_LOUD,
+                                ("The Key ID is %d\n", entry_no));
+                       RT_TRACE(COMP_SEC, DBG_LOUD,
+                                ("WRITE %x: %x \n",
+                                 rtlpriv->cfg->maps[RWCAM], target_command));
+
+               } else if (entry_i == 1) {
+
+                       target_content = (u32) (*(mac_addr + 5)) << 24 |
+                           (u32) (*(mac_addr + 4)) << 16 |
+                           (u32) (*(mac_addr + 3)) << 8 |
+                           (u32) (*(mac_addr + 2));
+
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+                                       target_content);
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+                                       target_command);
+
+                       RT_TRACE(COMP_SEC, DBG_LOUD,
+                                ("WRITE A4: %x \n", target_content));
+                       RT_TRACE(COMP_SEC, DBG_LOUD,
+                                ("WRITE A0: %x \n", target_command));
+
+               } else {
+
+                       target_content =
+                           (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) <<
+                           24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2))
+                           << 16 |
+                           (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8
+                           | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0));
+
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
+                                       target_content);
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+                                       target_command);
+                       udelay(100);
+
+                       RT_TRACE(COMP_SEC, DBG_LOUD,
+                                ("WRITE A4: %x \n", target_content));
+                       RT_TRACE(COMP_SEC, DBG_LOUD,
+                                ("WRITE A0: %x \n", target_command));
+               }
+       }
+
+       RT_TRACE(COMP_SEC, DBG_LOUD,
+                ("after set key, usconfig:%x\n", us_config));
+}
+
+u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+                        u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
+                        u32 ul_default_key, u8 *key_content)
+{
+       u32 us_config;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_SEC, DBG_DMESG,
+                ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, "
+                 "ulUseDK=%x MacAddr %pM\n",
+                 ul_entry_idx, ul_key_id, ul_enc_alg,
+                 ul_default_key, mac_addr));
+
+       if (ul_key_id == TOTAL_CAM_ENTRY) {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("ulKeyId exceed!\n"));
+               return 0;
+       }
+
+       if (ul_default_key == 1) {
+               us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2);
+       } else {
+               us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id;
+       }
+
+       rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
+                             (u8 *) key_content, us_config);
+
+       RT_TRACE(COMP_SEC, DBG_DMESG, ("end \n"));
+
+       return 1;
+
+}
+//EXPORT_SYMBOL(rtl_cam_add_one_entry);
+
+int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
+                            u8 *mac_addr, u32 ul_key_id)
+{
+       u32 ul_command;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id));
+
+       ul_command = ul_key_id * CAM_CONTENT_COUNT;
+       ul_command = ul_command | BIT(31) | BIT(16);
+
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0);
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+       RT_TRACE(COMP_SEC, DBG_DMESG,
+                ("rtl_cam_delete_one_entry(): WRITE A4: %x \n", 0));
+       RT_TRACE(COMP_SEC, DBG_DMESG,
+                ("rtl_cam_delete_one_entry(): WRITE A0: %x \n", ul_command));
+
+       return 0;
+
+}
+//EXPORT_SYMBOL(rtl_cam_delete_one_entry);
+
+void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
+{
+       u32 ul_command;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       ul_command = BIT(31) | BIT(30);
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+}
+//EXPORT_SYMBOL(rtl_cam_reset_all_entry);
+
+void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       u32 ul_command;
+       u32 ul_content;
+       u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+
+       switch (rtlpriv->sec.pairwise_enc_algorithm) {
+       case WEP40_ENCRYPTION:
+               ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
+               break;
+       case WEP104_ENCRYPTION:
+               ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
+               break;
+       case TKIP_ENCRYPTION:
+               ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
+               break;
+       case AESCCMP_ENCRYPTION:
+               ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+               break;
+       default:
+               ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
+       }
+
+       ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2);
+
+       ul_content |= BIT(15);
+       ul_command = CAM_CONTENT_COUNT * uc_index;
+       ul_command = ul_command | BIT(31) | BIT(16);
+
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+       RT_TRACE(COMP_SEC, DBG_DMESG,
+                ("rtl_cam_mark_invalid(): WRITE A4: %x \n", ul_content));
+       RT_TRACE(COMP_SEC, DBG_DMESG,
+                ("rtl_cam_mark_invalid(): WRITE A0: %x \n", ul_command));
+}
+//EXPORT_SYMBOL(rtl_cam_mark_invalid);
+
+void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       u32 ul_command;
+       u32 ul_content;
+       u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+       u8 entry_i;
+
+       switch (rtlpriv->sec.pairwise_enc_algorithm) {
+       case WEP40_ENCRYPTION:
+               ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
+               break;
+       case WEP104_ENCRYPTION:
+               ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
+               break;
+       case TKIP_ENCRYPTION:
+               ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
+               break;
+       case AESCCMP_ENCRYPTION:
+               ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+               break;
+       default:
+               ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
+       }
+
+       for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+
+               if (entry_i == 0) {
+                       ul_content =
+                           (uc_index & 0x03) | ((u16) (ul_encalgo) << 2);
+                       ul_content |= BIT(15);
+
+               } else {
+                       ul_content = 0;
+               }
+
+               ul_command = CAM_CONTENT_COUNT * uc_index + entry_i;
+               ul_command = ul_command | BIT(31) | BIT(16);
+
+               rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
+               rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
+
+               RT_TRACE(COMP_SEC, DBG_LOUD,
+                        ("rtl_cam_empty_entry(): WRITE A4: %x \n",
+                         ul_content));
+               RT_TRACE(COMP_SEC, DBG_LOUD,
+                        ("rtl_cam_empty_entry(): WRITE A0: %x \n",
+                         ul_command));
+       }
+
+}
+//EXPORT_SYMBOL(rtl_cam_empty_entry);
+
+u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4;
+       u8 entry_idx = 0;
+       u8 i, *addr;
+
+       if (NULL == sta_addr) {
+               RT_TRACE(COMP_SEC, DBG_EMERG,
+                       ("sta_addr is NULL.\n"));
+               return TOTAL_CAM_ENTRY;
+       }
+       /* Does STA already exist? */
+       for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
+               addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
+               if(memcmp(addr, sta_addr, ETH_ALEN) == 0)
+                       return i;
+       }
+       /* Get a free CAM entry. */
+       for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) {
+               if ((bitmap & BIT(0)) == 0) {
+                       RT_TRACE(COMP_SEC, DBG_EMERG,
+                               ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
+                                rtlpriv->sec.hwsec_cam_bitmap, entry_idx));
+                       rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx;
+                       memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx],
+                              sta_addr, ETH_ALEN);
+                       return entry_idx;
+               }
+               bitmap = bitmap >>1;
+       }
+       return TOTAL_CAM_ENTRY;
+}
+//EXPORT_SYMBOL(rtl_cam_get_free_entry);
+
+void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 bitmap;
+       u8 i, *addr;
+
+       if (NULL == sta_addr) {
+               RT_TRACE(COMP_SEC, DBG_EMERG,
+                       ("sta_addr is NULL.\n"));
+       }
+
+       if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\
+                               sta_addr[4]|sta_addr[5]) == 0) {
+               RT_TRACE(COMP_SEC, DBG_EMERG,
+                       ("sta_addr is 00:00:00:00:00:00.\n"));
+               return;
+       }
+       /* Does STA already exist? */
+       for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
+               addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
+               bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i;
+               if (((bitmap & BIT(0)) == BIT(0)) &&
+                   (memcmp(addr, sta_addr, ETH_ALEN) == 0)) {
+                       /* Remove from HW Security CAM */
+                       memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN);
+                       rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
+                       printk("&&&&&&&&&del entry %d\n",i);
+               }
+       }
+       return;
+}
+//EXPORT_SYMBOL(rtl_cam_del_entry);
diff --git a/drivers/staging/rtl8821ae/cam.h b/drivers/staging/rtl8821ae/cam.h
new file mode 100644 (file)
index 0000000..326fa67
--- /dev/null
@@ -0,0 +1,56 @@
+/******************************************************************************
+ *
+ * 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_CAM_H_
+#define __RTL_CAM_H_
+
+#define CAM_CONTENT_COUNT                              8
+
+#define CFG_DEFAULT_KEY                                BIT(5)
+#define CFG_VALID                                      BIT(15)
+
+#define PAIRWISE_KEYIDX                                        0
+#define CAM_PAIRWISE_KEY_POSITION                      4
+
+#define        CAM_CONFIG_USEDK                                1
+#define        CAM_CONFIG_NO_USEDK                             0
+
+extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
+extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+                               u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
+                               u32 ul_default_key, u8 *key_content);
+int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
+                            u32 ul_key_id);
+void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
+void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
+void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
+u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr);
+void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr);
+
+#endif
diff --git a/drivers/staging/rtl8821ae/compat.h b/drivers/staging/rtl8821ae/compat.h
new file mode 100644 (file)
index 0000000..68269cc
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef __RTL_COMPAT_H__
+#define __RTL_COMPAT_H__
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+/*
+ * Use this if you want to use the same suspend and resume callbacks for suspend
+ * to RAM and hibernation.
+ */
+#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
+struct dev_pm_ops name = { \
+       .suspend = suspend_fn, \
+       .resume = resume_fn, \
+       .freeze = suspend_fn, \
+       .thaw = resume_fn, \
+       .poweroff = suspend_fn, \
+       .restore = resume_fn, \
+}
+
+#define compat_pci_suspend(fn)                                         \
+       int fn##_compat(struct pci_dev *pdev, pm_message_t state)       \
+       {                                                               \
+               int r;                                                  \
+                                                                       \
+               r = fn(&pdev->dev);                                     \
+               if (r)                                                  \
+                       return r;                                       \
+                                                                       \
+               pci_save_state(pdev);                                   \
+               pci_disable_device(pdev);                               \
+               pci_set_power_state(pdev, PCI_D3hot);                   \
+                                                                       \
+               return 0;                                               \
+       }
+
+#define compat_pci_resume(fn)                                          \
+       int fn##_compat(struct pci_dev *pdev)                           \
+       {                                                               \
+               int r;                                                  \
+                                                                       \
+               pci_set_power_state(pdev, PCI_D0);                      \
+               r = pci_enable_device(pdev);                            \
+               if (r)                                                  \
+                       return r;                                       \
+               pci_restore_state(pdev);                                \
+                                                                       \
+               return fn(&pdev->dev);                                  \
+       }
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+#define RX_FLAG_MACTIME_MPDU RX_FLAG_TSFT
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+#define RX_FLAG_MACTIME_MPDU RX_FLAG_MACTIME_START
+#else
+#endif
+//#define NETDEV_TX_OK
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
+#define IEEE80211_KEY_FLAG_SW_MGMT IEEE80211_KEY_FLAG_SW_MGMT_TX
+#endif
+
+struct ieee80211_mgmt_compat {
+       __le16 frame_control;
+       __le16 duration;
+       u8 da[6];
+       u8 sa[6];
+       u8 bssid[6];
+       __le16 seq_ctrl;
+       union {
+               struct {
+                       u8 category;
+                       union {
+                               struct {
+                                       u8 action_code;
+                                       u8 dialog_token;
+                                       u8 status_code;
+                                       u8 variable[0];
+                               } __attribute__ ((packed)) wme_action;
+                               struct{
+                                       u8 action_code;
+                                       u8 dialog_token;
+                                       __le16 capab;
+                                       __le16 timeout;
+                                       __le16 start_seq_num;
+                               } __attribute__((packed)) addba_req;
+                               struct{
+                                       u8 action_code;
+                                       u8 dialog_token;
+                                       __le16 status;
+                                       __le16 capab;
+                                       __le16 timeout;
+                               } __attribute__((packed)) addba_resp;
+                               struct{
+                                       u8 action_code;
+                                       __le16 params;
+                                       __le16 reason_code;
+                               } __attribute__((packed)) delba;
+                               struct{
+                                       u8 action_code;
+                                       /* capab_info for open and confirm,
+                                        * reason for close
+                                        */
+                                       __le16 aux;
+                                       /* Followed in plink_confirm by status
+                                        * code, AID and supported rates,
+                                        * and directly by supported rates in
+                                        * plink_open and plink_close
+                                        */
+                                       u8 variable[0];
+                               } __attribute__((packed)) plink_action;
+                               struct{
+                                       u8 action_code;
+                                       u8 variable[0];
+                               } __attribute__((packed)) mesh_action;
+                               struct {
+                                       u8 action;
+                                       u8 smps_control;
+                               } __attribute__ ((packed)) ht_smps;
+                       } u;
+               } __attribute__ ((packed)) action;
+       } u;
+} __attribute__ ((packed));
+#endif
diff --git a/drivers/staging/rtl8821ae/core.c b/drivers/staging/rtl8821ae/core.c
new file mode 100644 (file)
index 0000000..40de608
--- /dev/null
@@ -0,0 +1,1464 @@
+/******************************************************************************
+ *
+ * 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 "wifi.h"
+#include "core.h"
+#include "cam.h"
+#include "base.h"
+#include "ps.h"
+
+#include "btcoexist/rtl_btc.h"
+
+/*mutex for start & stop is must here. */
+static int rtl_op_start(struct ieee80211_hw *hw)
+{
+       int err = 0;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       if (!is_hal_stop(rtlhal))
+               return 0;
+       if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+               return 0;
+       mutex_lock(&rtlpriv->locks.conf_mutex);
+       err = rtlpriv->intf_ops->adapter_start(hw);
+       if (err)
+               goto out;
+       rtl_watch_dog_timer_callback((unsigned long)hw);
+
+out:
+       mutex_unlock(&rtlpriv->locks.conf_mutex);
+       return err;
+}
+
+static void rtl_op_stop(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       if (is_hal_stop(rtlhal))
+               return;
+
+       /* here is must, because adhoc do stop and start,
+        * but stop with RFOFF may cause something wrong,
+        * like adhoc TP */
+       if (unlikely(ppsc->rfpwr_state == ERFOFF))
+               rtl_ips_nic_on(hw);
+
+       mutex_lock(&rtlpriv->locks.conf_mutex);
+
+       mac->link_state = MAC80211_NOLINK;
+       memset(mac->bssid, 0, 6);
+       mac->vendor = PEER_UNKNOWN;
+
+       /*reset sec info */
+       rtl_cam_reset_sec_info(hw);
+
+       rtl_deinit_deferred_work(hw);
+       rtlpriv->intf_ops->adapter_stop(hw);
+
+       mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+static int rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       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 rtl_tcb_desc tcb_desc;
+       memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+       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->intf_ops->waitq_insert(hw, skb))
+               rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+
+       return NETDEV_TX_OK;
+
+err_free:
+       dev_kfree_skb_any(skb);
+       return NETDEV_TX_OK;
+}
+#else
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+#else
+/*<delete in kernel end>*/
+static void rtl_op_tx(struct ieee80211_hw *hw,
+                     struct ieee80211_tx_control *control,
+                     struct sk_buff *skb)
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+{
+       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 rtl_tcb_desc tcb_desc;
+       memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+       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;
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+       if (!rtlpriv->intf_ops->waitq_insert(hw, skb))
+               rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+#else
+/*<delete in kernel end>*/
+       if (!rtlpriv->intf_ops->waitq_insert(hw, control->sta, skb))
+               rtlpriv->intf_ops->adapter_tx(hw, control->sta, skb, &tcb_desc);
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+       return;
+
+err_free:
+       dev_kfree_skb_any(skb);
+       return;
+}
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+
+static int rtl_op_add_interface(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       int err = 0;
+
+       if (mac->vif) {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
+               return -EOPNOTSUPP;
+       }
+
+/*This flag is not defined before kernel 3.4*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
+       vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+#endif
+
+       rtl_ips_nic_on(hw);
+
+       mutex_lock(&rtlpriv->locks.conf_mutex);
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+       switch (ieee80211_vif_type_p2p(vif)) {
+       case NL80211_IFTYPE_P2P_CLIENT:
+               mac->p2p = P2P_ROLE_CLIENT;
+               /*fall through*/
+#else
+/*<delete in kernel end>*/
+       switch (vif->type) {
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+       case NL80211_IFTYPE_STATION:
+               if (mac->beacon_enabled == 1) {
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("NL80211_IFTYPE_STATION \n"));
+                       mac->beacon_enabled = 0;
+                       rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+                                       rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);
+               }
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                        ("NL80211_IFTYPE_ADHOC \n"));
+
+               mac->link_state = MAC80211_LINKED;
+               rtlpriv->cfg->ops->set_bcn_reg(hw);
+               if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+                       mac->basic_rates = 0xfff;
+               else
+                       mac->basic_rates = 0xff0;
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+                               (u8 *) (&mac->basic_rates));
+
+               break;
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+       case NL80211_IFTYPE_P2P_GO:
+               mac->p2p = P2P_ROLE_GO;
+               /*fall through*/
+#endif
+/*<delete in kernel end>*/
+       case NL80211_IFTYPE_AP:
+               RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                        ("NL80211_IFTYPE_AP \n"));
+
+               mac->link_state = MAC80211_LINKED;
+               rtlpriv->cfg->ops->set_bcn_reg(hw);
+               if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+                       mac->basic_rates = 0xfff;
+               else
+                       mac->basic_rates = 0xff0;
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+                                             (u8 *) (&mac->basic_rates));
+               break;
+       case NL80211_IFTYPE_MESH_POINT:
+               RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                        ("NL80211_IFTYPE_MESH_POINT \n"));
+
+               mac->link_state = MAC80211_LINKED;
+               rtlpriv->cfg->ops->set_bcn_reg(hw);
+               if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+                       mac->basic_rates = 0xfff;
+               else
+                       mac->basic_rates = 0xff0;
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+                               (u8 *) (&mac->basic_rates));
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("operation mode %d is not support!\n", vif->type));
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+#ifdef VIF_TODO
+       if (!rtl_set_vif_info(hw, vif))
+               goto out;
+#endif
+
+       if (mac->p2p) {
+               RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                        ("p2p role %x \n",vif->type));
+               mac->basic_rates = 0xff0;/*disable cck rate for p2p*/
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+                               (u8 *) (&mac->basic_rates));
+       }
+       mac->vif = vif;
+       mac->opmode = vif->type;
+       rtlpriv->cfg->ops->set_network_type(hw, vif->type);
+       memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
+
+out:
+       mutex_unlock(&rtlpriv->locks.conf_mutex);
+       return err;
+}
+
+static void rtl_op_remove_interface(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+       mutex_lock(&rtlpriv->locks.conf_mutex);
+
+       /* Free beacon resources */
+       if ((vif->type == NL80211_IFTYPE_AP) ||
+           (vif->type == NL80211_IFTYPE_ADHOC) ||
+           (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+               if (mac->beacon_enabled == 1) {
+                       mac->beacon_enabled = 0;
+                       rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+                                       rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);
+               }
+       }
+
+       /*
+        *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
+        *NO LINK for our hardware.
+        */
+       mac->p2p = 0;
+       mac->vif = NULL;
+       mac->link_state = MAC80211_NOLINK;
+       memset(mac->bssid, 0, 6);
+       mac->vendor = PEER_UNKNOWN;
+       mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
+       rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
+
+       mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+/*<delete in kernel end>*/
+static int rtl_op_change_interface(struct ieee80211_hw *hw,
+                                  struct ieee80211_vif *vif,
+                                  enum nl80211_iftype new_type, bool p2p)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int ret;
+       rtl_op_remove_interface(hw, vif);
+
+       vif->type = new_type;
+       vif->p2p = p2p;
+       ret = rtl_op_add_interface(hw, vif);
+       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                (" p2p  %x\n",p2p));
+       return ret;
+}
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct ieee80211_conf *conf = &hw->conf;
+
+       if (mac->skip_scan)
+               return 1;
+
+
+       mutex_lock(&rtlpriv->locks.conf_mutex);
+       if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {  /* BIT(2) */
+               RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                        ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
+       }
+
+       /*For IPS */
+       if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+               if (hw->conf.flags & IEEE80211_CONF_IDLE)
+                       rtl_ips_nic_off(hw);
+               else
+                       rtl_ips_nic_on(hw);
+       } else {
+               /*
+                *although rfoff may not cause by ips, but we will
+                *check the reason in set_rf_power_state function
+                */
+               if (unlikely(ppsc->rfpwr_state == ERFOFF))
+                       rtl_ips_nic_on(hw);
+       }
+
+       /*For LPS */
+       if (changed & IEEE80211_CONF_CHANGE_PS) {
+               cancel_delayed_work(&rtlpriv->works.ps_work);
+               cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
+               if (conf->flags & IEEE80211_CONF_PS) {
+                       rtlpriv->psc.sw_ps_enabled = true;
+                       /* sleep here is must, or we may recv the beacon and
+                        * cause mac80211 into wrong ps state, this will cause
+                        * power save nullfunc send fail, and further cause
+                        * pkt loss, So sleep must quickly but not immediatly
+                        * because that will cause nullfunc send by mac80211
+                        * fail, and cause pkt loss, we have tested that 5mA
+                        * is worked very well */
+                       if (!rtlpriv->psc.multi_buffered)
+                               queue_delayed_work(rtlpriv->works.rtl_wq,
+                                                  &rtlpriv->works.ps_work,
+                                                  MSECS(5));
+               } else {
+                       rtl_swlps_rf_awake(hw);
+                       rtlpriv->psc.sw_ps_enabled = false;
+               }
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+               RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                        ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
+                         hw->conf.long_frame_max_tx_count));
+               mac->retry_long = hw->conf.long_frame_max_tx_count;
+               mac->retry_short = hw->conf.long_frame_max_tx_count;
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+                               (u8 *) (&hw->conf.long_frame_max_tx_count));
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+               struct ieee80211_channel *channel = hw->conf.chandef.chan;
+               enum nl80211_channel_type channel_type =
+                               cfg80211_get_chandef_type(&(hw->conf.chandef));
+#else
+               struct ieee80211_channel *channel = hw->conf.channel;
+               enum nl80211_channel_type channel_type = hw->conf.channel_type;
+#endif
+               u8 wide_chan = (u8) channel->hw_value;
+
+               if (mac->act_scanning)
+                       mac->n_channels++;
+
+               if (rtlpriv->dm.supp_phymode_switch &&
+                       mac->link_state < MAC80211_LINKED &&
+                       !mac->act_scanning) {
+                       if (rtlpriv->cfg->ops->check_switch_to_dmdp)
+                               rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
+               }
+
+               /*
+                *because we should back channel to
+                *current_network.chan in in scanning,
+                *So if set_chan == current_network.chan
+                *we should set it.
+                *because mac80211 tell us wrong bw40
+                *info for cisco1253 bw20, so we modify
+                *it here based on UPPER & LOWER
+                */
+               switch (channel_type) {
+                       case NL80211_CHAN_HT20:
+                       case NL80211_CHAN_NO_HT:
+                               /* SC */
+                               mac->cur_40_prime_sc =
+                                       PRIME_CHNL_OFFSET_DONT_CARE;
+                               rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
+                               mac->bw_40 = false;
+                               break;
+                       case NL80211_CHAN_HT40MINUS:
+                               /* SC */
+                               mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
+                               rtlphy->current_chan_bw =
+                                       HT_CHANNEL_WIDTH_20_40;
+                               mac->bw_40 = true;
+
+                               /*wide channel */
+                               wide_chan -= 2;
+
+                               break;
+                       case NL80211_CHAN_HT40PLUS:
+                               /* SC */
+                               mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
+                               rtlphy->current_chan_bw =
+                                       HT_CHANNEL_WIDTH_20_40;
+                               mac->bw_40 = true;
+
+                               /*wide channel */
+                               wide_chan += 2;
+
+                               break;
+                       default:
+                               mac->bw_40 = false;
+                               RT_TRACE(COMP_ERR, DBG_EMERG,
+                                               ("switch case not processed \n"));
+                               break;
+               }
+
+               if (wide_chan <= 0)
+                       wide_chan = 1;
+
+               /* in scanning, when before we offchannel we may send a ps=1
+                * null to AP, and then we may send a ps = 0 null to AP quickly,
+                * but first null have cause AP's put lots of packet to hw tx
+                * buffer, these packet must be tx before off channel so we must
+                * delay more time to let AP flush these packets before
+                * offchannel, or dis-association or delete BA will happen by AP
+                */
+               if (rtlpriv->mac80211.offchan_deley) {
+                       rtlpriv->mac80211.offchan_deley = false;
+                       mdelay(50);
+               }
+
+               rtlphy->current_channel = wide_chan;
+
+               rtlpriv->cfg->ops->switch_channel(hw);
+               rtlpriv->cfg->ops->set_channel_access(hw);
+               rtlpriv->cfg->ops->set_bw_mode(hw,
+                       channel_type);
+       }
+
+       mutex_unlock(&rtlpriv->locks.conf_mutex);
+
+       return 0;
+}
+
+static void rtl_op_configure_filter(struct ieee80211_hw *hw,
+                                   unsigned int changed_flags,
+                                   unsigned int *new_flags, u64 multicast)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+       *new_flags &= RTL_SUPPORTED_FILTERS;
+       if (0 == changed_flags)
+               return;
+
+       /*TODO: we disable broadcase now, so enable here */
+       if (changed_flags & FIF_ALLMULTI) {
+               if (*new_flags & FIF_ALLMULTI) {
+                       mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
+                           rtlpriv->cfg->maps[MAC_RCR_AB];
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("Enable receive multicast frame.\n"));
+               } else {
+                       mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
+                                         rtlpriv->cfg->maps[MAC_RCR_AB]);
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("Disable receive multicast frame.\n"));
+               }
+       }
+
+       if (changed_flags & FIF_FCSFAIL) {
+               if (*new_flags & FIF_FCSFAIL) {
+                       mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("Enable receive FCS error frame.\n"));
+               } else {
+                       mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("Disable receive FCS error frame.\n"));
+               }
+       }
+
+       /* if ssid not set to hw don't check bssid
+        * here just used for linked scanning, & linked
+        * and nolink check bssid is set in set network_type */
+       if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
+               (mac->link_state >= MAC80211_LINKED)) {
+               if (mac->opmode != NL80211_IFTYPE_AP &&
+                       mac->opmode != NL80211_IFTYPE_MESH_POINT) {
+                       if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
+                               rtlpriv->cfg->ops->set_chk_bssid(hw, false);
+                       } else {
+                               rtlpriv->cfg->ops->set_chk_bssid(hw, true);
+                       }
+               }
+       }
+
+       if (changed_flags & FIF_CONTROL) {
+               if (*new_flags & FIF_CONTROL) {
+                       mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
+
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("Enable receive control frame.\n"));
+               } else {
+                       mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("Disable receive control frame.\n"));
+               }
+       }
+
+       if (changed_flags & FIF_OTHER_BSS) {
+               if (*new_flags & FIF_OTHER_BSS) {
+                       mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("Enable receive other BSS's frame.\n"));
+               } else {
+                       mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
+                       RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                                ("Disable receive other BSS's frame.\n"));
+               }
+       }
+}
+static int rtl_op_sta_add(struct ieee80211_hw *hw,
+                        struct ieee80211_vif *vif,
+                        struct ieee80211_sta *sta)
+{
+       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));
+       struct rtl_sta_info *sta_entry;
+
+       if (sta) {
+               sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+               spin_lock_bh(&rtlpriv->locks.entry_list_lock);
+               list_add_tail(&sta_entry->list, &rtlpriv->entry_list);
+               spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
+               if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                       sta_entry->wireless_mode = WIRELESS_MODE_G;
+                       if (sta->supp_rates[0] <= 0xf)
+                               sta_entry->wireless_mode = WIRELESS_MODE_B;
+                       if (sta->ht_cap.ht_supported == true)
+                               sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
+
+                       if (vif->type == NL80211_IFTYPE_ADHOC)
+                               sta_entry->wireless_mode = WIRELESS_MODE_G;
+               } else if (rtlhal->current_bandtype == BAND_ON_5G) {
+                       sta_entry->wireless_mode = WIRELESS_MODE_A;
+                       if (sta->ht_cap.ht_supported == true)
+                               sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
+
+                       if (vif->type == NL80211_IFTYPE_ADHOC)
+                               sta_entry->wireless_mode = WIRELESS_MODE_A;
+               }
+               /*disable cck rate for p2p*/
+               if (mac->p2p)
+                       sta->supp_rates[0] &= 0xfffffff0;
+
+               memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN);
+               RT_TRACE(COMP_MAC80211, DBG_DMESG,
+                       ("Add sta addr is %pM\n",sta->addr));
+               rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
+       }
+
+       return 0;
+}
+
+static int rtl_op_sta_remove(struct ieee80211_hw *hw,
+                               struct ieee80211_vif *vif,
+                               struct ieee80211_sta *sta)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_sta_info *sta_entry;
+       if (sta) {
+               RT_TRACE(COMP_MAC80211, DBG_DMESG,
+                       ("Remove sta addr is %pM\n",sta->addr));
+               sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+               sta_entry->wireless_mode = 0;
+               sta_entry->ratr_index = 0;
+               spin_lock_bh(&rtlpriv->locks.entry_list_lock);
+               list_del(&sta_entry->list);
+               spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
+       }
+       return 0;
+}
+static int _rtl_get_hal_qnum(u16 queue)
+{
+       int qnum;
+
+       switch (queue) {
+       case 0:
+               qnum = AC3_VO;
+               break;
+       case 1:
+               qnum = AC2_VI;
+               break;
+       case 2:
+               qnum = AC0_BE;
+               break;
+       case 3:
+               qnum = AC1_BK;
+               break;
+       default:
+               qnum = AC0_BE;
+               break;
+       }
+       return qnum;
+}
+
+/*
+ *for mac80211 VO=0, VI=1, BE=2, BK=3
+ *for rtl819x  BE=0, BK=1, VI=2, VO=3
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+static int rtl_op_conf_tx(struct ieee80211_hw *hw,
+                         struct ieee80211_vif *vif, u16 queue,
+                         const struct ieee80211_tx_queue_params *param)
+#else
+static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                         const struct ieee80211_tx_queue_params *param)
+#endif
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       int aci;
+
+       if (queue >= AC_MAX) {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("queue number %d is incorrect!\n", queue));
+               return -EINVAL;
+       }
+
+       aci = _rtl_get_hal_qnum(queue);
+       mac->ac[aci].aifs = param->aifs;
+       mac->ac[aci].cw_min = param->cw_min;
+       mac->ac[aci].cw_max = param->cw_max;
+       mac->ac[aci].tx_op = param->txop;
+       memcpy(&mac->edca_param[aci], param, sizeof(*param));
+       rtlpriv->cfg->ops->set_qos(hw, aci);
+       return 0;
+}
+
+static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+                                   struct ieee80211_bss_conf *bss_conf,
+                                   u32 changed)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       mutex_lock(&rtlpriv->locks.conf_mutex);
+       if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+           (vif->type == NL80211_IFTYPE_AP) ||
+           (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+               if ((changed & BSS_CHANGED_BEACON) ||
+                   (changed & BSS_CHANGED_BEACON_ENABLED &&
+                    bss_conf->enable_beacon)) {
+                       if (mac->beacon_enabled == 0) {
+                               RT_TRACE(COMP_MAC80211, DBG_DMESG,
+                                        ("BSS_CHANGED_BEACON_ENABLED \n"));
+
+                               /*start hw beacon interrupt. */
+                               /*rtlpriv->cfg->ops->set_bcn_reg(hw); */
+                               mac->beacon_enabled = 1;
+                               rtlpriv->cfg->ops->update_interrupt_mask(hw,
+                                               rtlpriv->cfg->maps
+                                               [RTL_IBSS_INT_MASKS], 0);
+
+                               if (rtlpriv->cfg->ops->linked_set_reg)
+                                       rtlpriv->cfg->ops->linked_set_reg(hw);
+                       }
+               }
+               if ((changed & BSS_CHANGED_BEACON_ENABLED &&
+                       !bss_conf->enable_beacon)){
+                       if (mac->beacon_enabled == 1) {
+                               RT_TRACE(COMP_MAC80211, DBG_DMESG,
+                                        ("ADHOC DISABLE BEACON\n"));
+
+                               mac->beacon_enabled = 0;
+                               rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+                                               rtlpriv->cfg->maps
+                                               [RTL_IBSS_INT_MASKS]);
+                       }
+               }
+               if (changed & BSS_CHANGED_BEACON_INT) {
+                       RT_TRACE(COMP_BEACON, DBG_TRACE,
+                                ("BSS_CHANGED_BEACON_INT\n"));
+                       mac->beacon_interval = bss_conf->beacon_int;
+                       rtlpriv->cfg->ops->set_bcn_intv(hw);
+               }
+       }
+
+       /*TODO: reference to enum ieee80211_bss_change */
+       if (changed & BSS_CHANGED_ASSOC) {
+               if (bss_conf->assoc) {
+                       struct ieee80211_sta *sta = NULL;
+                       /* we should reset all sec info & cam
+                        * before set cam after linked, we should not
+                        * reset in disassoc, that will cause tkip->wep
+                        * fail because some flag will be wrong */
+                       /* reset sec info */
+                       rtl_cam_reset_sec_info(hw);
+                       /* reset cam to fix wep fail issue
+                        * when change from wpa to wep */
+                       rtl_cam_reset_all_entry(hw);
+
+                       mac->link_state = MAC80211_LINKED;
+                       mac->cnt_after_linked = 0;
+                       mac->assoc_id = bss_conf->aid;
+                       memcpy(mac->bssid, bss_conf->bssid, 6);
+
+                       if (rtlpriv->cfg->ops->linked_set_reg)
+                               rtlpriv->cfg->ops->linked_set_reg(hw);
+
+                       rcu_read_lock();
+                       sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
+
+                       if (vif->type == NL80211_IFTYPE_STATION && sta)
+                               rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
+                       RT_TRACE(COMP_EASY_CONCURRENT, DBG_LOUD,
+                                       ("send PS STATIC frame \n"));
+                       if (rtlpriv->dm.supp_phymode_switch) {
+                               if (sta->ht_cap.ht_supported)
+                                       rtl_send_smps_action(hw, sta,
+                                                       IEEE80211_SMPS_STATIC);
+                       }
+                       rcu_read_unlock();
+
+                       RT_TRACE(COMP_MAC80211, DBG_DMESG,
+                                ("BSS_CHANGED_ASSOC\n"));
+               } else {
+                       if (mac->link_state == MAC80211_LINKED)
+                               rtl_lps_leave(hw);
+                       if (ppsc->p2p_ps_info.p2p_ps_mode> P2P_PS_NONE)
+                               rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+                       mac->link_state = MAC80211_NOLINK;
+                       memset(mac->bssid, 0, 6);
+                       mac->vendor = PEER_UNKNOWN;
+
+                       if (rtlpriv->dm.supp_phymode_switch) {
+                               if (rtlpriv->cfg->ops->check_switch_to_dmdp)
+                                       rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
+                       }
+                       RT_TRACE(COMP_MAC80211, DBG_DMESG,
+                                ("BSS_CHANGED_UN_ASSOC\n"));
+               }
+       }
+
+       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+               RT_TRACE(COMP_MAC80211, DBG_TRACE,
+                        ("BSS_CHANGED_ERP_CTS_PROT\n"));
+               mac->use_cts_protect = bss_conf->use_cts_prot;
+       }
+
+       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+               RT_TRACE(COMP_MAC80211, DBG_LOUD,
+                        ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x \n",
+                         bss_conf->use_short_preamble));
+
+               mac->short_preamble = bss_conf->use_short_preamble;
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
+                                             (u8 *) (&mac->short_preamble));
+       }
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               RT_TRACE(COMP_MAC80211, DBG_TRACE,
+                        ("BSS_CHANGED_ERP_SLOT\n"));
+
+               if (bss_conf->use_short_slot)
+                       mac->slot_time = RTL_SLOT_TIME_9;
+               else
+                       mac->slot_time = RTL_SLOT_TIME_20;
+
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+                                             (u8 *) (&mac->slot_time));
+       }
+
+       if (changed & BSS_CHANGED_HT) {
+               struct ieee80211_sta *sta = NULL;
+
+               RT_TRACE(COMP_MAC80211, DBG_TRACE,
+                        ("BSS_CHANGED_HT\n"));
+
+               rcu_read_lock();
+               sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
+               if (sta) {
+                       if (sta->ht_cap.ampdu_density >
+                           mac->current_ampdu_density)
+                               mac->current_ampdu_density =
+                                   sta->ht_cap.ampdu_density;
+                       if (sta->ht_cap.ampdu_factor <
+                           mac->current_ampdu_factor)
+                               mac->current_ampdu_factor =
+                                   sta->ht_cap.ampdu_factor;
+               }
+               rcu_read_unlock();
+
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY,
+                                             (u8 *) (&mac->max_mss_density));
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR,
+                                             &mac->current_ampdu_factor);
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE,
+                                             &mac->current_ampdu_density);
+       }
+
+       if (changed & BSS_CHANGED_BSSID) {
+               u32 basic_rates;
+               struct ieee80211_sta *sta = NULL;
+
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
+                                             (u8 *) bss_conf->bssid);
+
+               RT_TRACE(COMP_MAC80211, DBG_DMESG,
+                        ("bssid: %pM\n", bss_conf->bssid));
+
+               mac->vendor = PEER_UNKNOWN;
+               memcpy(mac->bssid, bss_conf->bssid, 6);
+               rtlpriv->cfg->ops->set_network_type(hw, vif->type);
+
+               rcu_read_lock();
+               sta = ieee80211_find_sta(vif, (u8*)bss_conf->bssid);
+               if (!sta) {
+                       rcu_read_unlock();
+                       goto out;
+               }
+
+               if (rtlhal->current_bandtype == BAND_ON_5G) {
+                       mac->mode = WIRELESS_MODE_A;
+               } else {
+                       if (sta->supp_rates[0] <= 0xf)
+                               mac->mode = WIRELESS_MODE_B;
+                       else
+                               mac->mode = WIRELESS_MODE_G;
+               }
+
+               if (sta->ht_cap.ht_supported) {
+                       if (rtlhal->current_bandtype == BAND_ON_2_4G)
+                               mac->mode = WIRELESS_MODE_N_24G;
+                       else
+                               mac->mode = WIRELESS_MODE_N_5G;
+               }
+
+               /* just station need it, because ibss & ap mode will
+                * set in sta_add, and will be NULL here */
+               if (vif->type == NL80211_IFTYPE_STATION) {
+                       struct rtl_sta_info *sta_entry;
+                       sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+                       sta_entry->wireless_mode = mac->mode;
+               }
+
+               if (sta->ht_cap.ht_supported) {
+                       mac->ht_enable = true;
+
+                       /*
+                        * for cisco 1252 bw20 it's wrong
+                        * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+                        *      mac->bw_40 = true;
+                        * }
+                        * */
+               }
+
+               if (changed & BSS_CHANGED_BASIC_RATES) {
+                       /* for 5G must << RATE_6M_INDEX=4,
+                        * because 5G have no cck rate*/
+                       if (rtlhal->current_bandtype == BAND_ON_5G)
+                               basic_rates = sta->supp_rates[1] << 4;
+                       else
+                               basic_rates = sta->supp_rates[0];
+
+                       mac->basic_rates = basic_rates;
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+                                       (u8 *) (&basic_rates));
+               }
+               rcu_read_unlock();
+       }
+
+       /*
+        * For FW LPS and Keep Alive:
+        * To tell firmware we have connected
+        * to an AP. For 92SE/CE power save v2.
+        */
+       if (changed & BSS_CHANGED_ASSOC) {
+               if (bss_conf->assoc) {
+                       u8 keep_alive = 10;
+                       u8 mstatus = RT_MEDIA_CONNECT;
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                     HW_VAR_KEEP_ALIVE,
+                                                     (u8 *) (&keep_alive));
+
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                     HW_VAR_H2C_FW_JOINBSSRPT,
+                                                     (u8 *) (&mstatus));
+                       ppsc->report_linked = true;
+
+               } else {
+
+                       u8 mstatus = RT_MEDIA_DISCONNECT;
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                     HW_VAR_H2C_FW_JOINBSSRPT,
+                                                     (u8 *) (&mstatus));
+                       ppsc->report_linked = false;
+
+               }
+
+               if (rtlpriv->cfg->ops->get_btc_status()){
+                       rtlpriv->btcoexist.btc_ops->btc_mediastatus_notify(
+                                               rtlpriv, ppsc->report_linked);
+               }
+       }
+
+out:
+       mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+static u64 rtl_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+#else
+static u64 rtl_op_get_tsf(struct ieee80211_hw *hw)
+#endif
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u64 tsf;
+
+       rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf));
+       return tsf;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+static void rtl_op_set_tsf(struct ieee80211_hw *hw,
+                          struct ieee80211_vif *vif, u64 tsf)
+#else
+static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+#endif
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
+
+       mac->tsf = tsf;
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss));
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+static void rtl_op_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+#else
+static void rtl_op_reset_tsf(struct ieee80211_hw *hw)
+#endif
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp = 0;
+
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp));
+}
+
+static void rtl_op_sta_notify(struct ieee80211_hw *hw,
+                             struct ieee80211_vif *vif,
+                             enum sta_notify_cmd cmd,
+                             struct ieee80211_sta *sta)
+{
+       switch (cmd) {
+       case STA_NOTIFY_SLEEP:
+               break;
+       case STA_NOTIFY_AWAKE:
+               break;
+       default:
+               break;
+       }
+}
+
+static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *vif,
+                              enum ieee80211_ampdu_mlme_action action,
+                              struct ieee80211_sta *sta, u16 tid, u16 * ssn
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
+/*<delete in kernel end>*/
+                              ,u8 buf_size
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+                              )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       switch (action) {
+       case IEEE80211_AMPDU_TX_START:
+               RT_TRACE(COMP_MAC80211, DBG_TRACE,
+                        ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
+               return rtl_tx_agg_start(hw, vif, sta, tid, ssn);
+               break;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+       case IEEE80211_AMPDU_TX_STOP_CONT:
+       case IEEE80211_AMPDU_TX_STOP_FLUSH:
+       case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+#else
+       case IEEE80211_AMPDU_TX_STOP:
+#endif
+               RT_TRACE(COMP_MAC80211, DBG_TRACE,
+                        ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
+               return rtl_tx_agg_stop(hw, vif, sta, tid);
+               break;
+       case IEEE80211_AMPDU_TX_OPERATIONAL:
+               RT_TRACE(COMP_MAC80211, DBG_TRACE,
+                        ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
+               rtl_tx_agg_oper(hw, sta, tid);
+               break;
+       case IEEE80211_AMPDU_RX_START:
+               RT_TRACE(COMP_MAC80211, DBG_TRACE,
+                        ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid));
+               return rtl_rx_agg_start(hw, sta, tid);
+               break;
+       case IEEE80211_AMPDU_RX_STOP:
+               RT_TRACE(COMP_MAC80211, DBG_TRACE,
+                        ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid));
+               return rtl_rx_agg_stop(hw, sta, tid);
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("IEEE80211_AMPDU_ERR!!!!:\n"));
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
+static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+       RT_TRACE(COMP_MAC80211, DBG_LOUD, ("\n"));
+       mac->act_scanning = true;
+       /*rtlpriv->btcops->btc_scan_notify(rtlpriv, 0); */
+       if (rtlpriv->link_info.b_higher_busytraffic) {
+               mac->skip_scan = true;
+               return;
+       }
+
+       if (rtlpriv->dm.supp_phymode_switch) {
+               if (rtlpriv->cfg->ops->check_switch_to_dmdp)
+                       rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
+       }
+
+       if (mac->link_state == MAC80211_LINKED) {
+               rtl_lps_leave(hw);
+               mac->link_state = MAC80211_LINKED_SCANNING;
+       } else {
+               rtl_ips_nic_on(hw);
+       }
+
+       /* Dul mac */
+       rtlpriv->rtlhal.b_load_imrandiqk_setting_for2g = false;
+
+       rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
+
+       rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP_BAND0);
+
+}
+
+static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+       RT_TRACE(COMP_MAC80211, DBG_LOUD, ("\n"));
+       mac->act_scanning = false;
+       mac->skip_scan = false;
+       if (rtlpriv->link_info.b_higher_busytraffic) {
+               return;
+       }
+
+       /* p2p will use 1/6/11 to scan */
+       if (mac->n_channels == 3)
+               mac->p2p_in_use = true;
+       else
+               mac->p2p_in_use = false;
+       mac->n_channels = 0;
+       /* Dul mac */
+       rtlpriv->rtlhal.b_load_imrandiqk_setting_for2g = false;
+
+       if (mac->link_state == MAC80211_LINKED_SCANNING) {
+               mac->link_state = MAC80211_LINKED;
+               if (mac->opmode == NL80211_IFTYPE_STATION) {
+                       /* fix fwlps issue */
+                       rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
+               }
+       }
+
+       rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
+       /* rtlpriv->btcops->btc_scan_notify(rtlpriv, 1); */
+}
+
+static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+                         struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+                         struct ieee80211_key_conf *key)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 key_type = NO_ENCRYPTION;
+       u8 key_idx;
+       bool group_key = false;
+       bool wep_only = false;
+       int err = 0;
+       u8 mac_addr[ETH_ALEN];
+       u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+       u8 zero_addr[ETH_ALEN] = { 0 };
+
+       if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("not open hw encryption\n"));
+               return -ENOSPC; /*User disabled HW-crypto */
+       }
+       /* To support IBSS, use sw-crypto for GTK */
+       if(((vif->type == NL80211_IFTYPE_ADHOC) ||
+           (vif->type == NL80211_IFTYPE_MESH_POINT)) &&
+          !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+               return -ENOSPC;
+       RT_TRACE(COMP_SEC, DBG_DMESG,
+                ("%s hardware based encryption for keyidx: %d, mac: %pM\n",
+                 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
+                 sta ? sta->addr : bcast_addr));
+       rtlpriv->sec.being_setkey = true;
+       rtl_ips_nic_on(hw);
+       mutex_lock(&rtlpriv->locks.conf_mutex);
+       /* <1> get encryption alg */
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+/*<delete in kernel end>*/
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+               key_type = WEP40_ENCRYPTION;
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
+               break;
+       case WLAN_CIPHER_SUITE_WEP104:
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP104\n"));
+               key_type = WEP104_ENCRYPTION;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               key_type = TKIP_ENCRYPTION;
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               key_type = AESCCMP_ENCRYPTION;
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+               /* HW don't support CMAC encryption,
+                * use software CMAC encryption */
+               key_type = AESCMAC_ENCRYPTION;
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CMAC\n"));
+               RT_TRACE(COMP_SEC, DBG_DMESG,
+                               ("HW don't support CMAC encrypiton, "
+                               "use software CMAC encrypiton\n"));
+               err = -EOPNOTSUPP;
+               goto out_unlock;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("alg_err:%x!!!!:\n", key->cipher));
+               goto out_unlock;
+       }
+/*<delete in kernel start>*/
+#else
+       switch (key->alg) {
+       case ALG_WEP:
+               if (key->keylen == WLAN_KEY_LEN_WEP40) {
+                       key_type = WEP40_ENCRYPTION;
+                       RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
+               } else {
+                       RT_TRACE(COMP_SEC, DBG_DMESG,
+                                ("alg:WEP104\n"));
+                       key_type = WEP104_ENCRYPTION;
+               }
+               break;
+       case ALG_TKIP:
+               key_type = TKIP_ENCRYPTION;
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
+               break;
+       case ALG_CCMP:
+               key_type = AESCCMP_ENCRYPTION;
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
+               break;
+       case ALG_AES_CMAC:
+               /*HW don't support CMAC encryption, use software CMAC encryption */
+               key_type = AESCMAC_ENCRYPTION;
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CMAC\n"));
+               RT_TRACE(COMP_SEC, DBG_DMESG,
+                        ("HW don't support CMAC encrypiton, "
+                         "use software CMAC encrypiton\n"));
+               err = -EOPNOTSUPP;
+               goto out_unlock;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("alg_err:%x!!!!:\n", key->alg));
+               goto out_unlock;
+       }
+#endif
+/*<delete in kernel end>*/
+       if(key_type == WEP40_ENCRYPTION ||
+                       key_type == WEP104_ENCRYPTION ||
+                       vif->type == NL80211_IFTYPE_ADHOC)
+               rtlpriv->sec.use_defaultkey = true;
+
+       /* <2> get key_idx */
+       key_idx = (u8) (key->keyidx);
+       if (key_idx > 3)
+               goto out_unlock;
+       /* <3> if pairwise key enable_hw_sec */
+       group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
+
+       /* wep always be group key, but there are two conditions:
+        * 1) wep only: is just for wep enc, in this condition
+        * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION
+        * will be true & enable_hw_sec will be set when wep
+        * ke setting.
+        * 2) wep(group) + AES(pairwise): some AP like cisco
+        * may use it, in this condition enable_hw_sec will not
+        * be set when wep key setting */
+       /* we must reset sec_info after lingked before set key,
+        * or some flag will be wrong*/
+       if (vif->type == NL80211_IFTYPE_AP ||
+               vif->type == NL80211_IFTYPE_MESH_POINT) {
+               if (!group_key || key_type == WEP40_ENCRYPTION ||
+                       key_type == WEP104_ENCRYPTION) {
+                       if (group_key) {
+                               wep_only = true;
+                       }
+                       rtlpriv->cfg->ops->enable_hw_sec(hw);
+               }
+       } else {
+               if ((!group_key) || (vif->type == NL80211_IFTYPE_ADHOC) ||
+                   rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
+                       if (rtlpriv->sec.pairwise_enc_algorithm ==
+                           NO_ENCRYPTION &&
+                          (key_type == WEP40_ENCRYPTION ||
+                           key_type == WEP104_ENCRYPTION))
+                               wep_only = true;
+                       rtlpriv->sec.pairwise_enc_algorithm = key_type;
+                       RT_TRACE(COMP_SEC, DBG_DMESG,
+                                ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:"
+                                 "1 TKIP:2 AES:4 WEP104:5)\n", key_type));
+                       rtlpriv->cfg->ops->enable_hw_sec(hw);
+               }
+       }
+       /* <4> set key based on cmd */
+       switch (cmd) {
+       case SET_KEY:
+               if (wep_only) {
+                       RT_TRACE(COMP_SEC, DBG_DMESG,
+                                ("set WEP(group/pairwise) key\n"));
+                       /* Pairwise key with an assigned MAC address. */
+                       rtlpriv->sec.pairwise_enc_algorithm = key_type;
+                       rtlpriv->sec.group_enc_algorithm = key_type;
+                       /*set local buf about wep key. */
+                       memcpy(rtlpriv->sec.key_buf[key_idx],
+                              key->key, key->keylen);
+                       rtlpriv->sec.key_len[key_idx] = key->keylen;
+                       memcpy(mac_addr, zero_addr, ETH_ALEN);
+               } else if (group_key) { /* group key */
+                       RT_TRACE(COMP_SEC, DBG_DMESG,
+                                ("set group key\n"));
+                       /* group key */
+                       rtlpriv->sec.group_enc_algorithm = key_type;
+                       /*set local buf about group key. */
+                       memcpy(rtlpriv->sec.key_buf[key_idx],
+                              key->key, key->keylen);
+                       rtlpriv->sec.key_len[key_idx] = key->keylen;
+                       memcpy(mac_addr, bcast_addr, ETH_ALEN);
+               } else {        /* pairwise key */
+                       RT_TRACE(COMP_SEC, DBG_DMESG,
+                                ("set pairwise key\n"));
+                       if (!sta) {
+                               RT_ASSERT(false, ("pairwise key withnot"
+                                                 "mac_addr\n"));
+
+                               err = -EOPNOTSUPP;
+                               goto out_unlock;
+                       }
+                       /* Pairwise key with an assigned MAC address. */
+                       rtlpriv->sec.pairwise_enc_algorithm = key_type;
+                       /*set local buf about pairwise key. */
+                       memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX],
+                              key->key, key->keylen);
+                       rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen;
+                       rtlpriv->sec.pairwise_key =
+                           rtlpriv->sec.key_buf[PAIRWISE_KEYIDX];
+                       memcpy(mac_addr, sta->addr, ETH_ALEN);
+               }
+               rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,
+                                          group_key, key_type, wep_only,
+                                          false);
+               /* <5> tell mac80211 do something: */
+               /*must use sw generate IV, or can not work !!!!. */
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+               key->hw_key_idx = key_idx;
+               if (key_type == TKIP_ENCRYPTION)
+                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+               /*use software CCMP encryption for management frames (MFP) */
+               if (key_type == AESCCMP_ENCRYPTION)
+                       key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
+               break;
+       case DISABLE_KEY:
+               RT_TRACE(COMP_SEC, DBG_DMESG,
+                        ("disable key delete one entry\n"));
+               /*set local buf about wep key. */
+               if (vif->type == NL80211_IFTYPE_AP ||
+                       vif->type == NL80211_IFTYPE_MESH_POINT) {
+                       if (sta)
+                               rtl_cam_del_entry(hw, sta->addr);
+               }
+               memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
+               rtlpriv->sec.key_len[key_idx] = 0;
+               memcpy(mac_addr, zero_addr, ETH_ALEN);
+               /*
+                *mac80211 will delete entrys one by one,
+                *so don't use rtl_cam_reset_all_entry
+                *or clear all entry here.
+                */
+               rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("cmd_err:%x!!!!:\n", cmd));
+       }
+out_unlock:
+       mutex_unlock(&rtlpriv->locks.conf_mutex);
+       rtlpriv->sec.being_setkey = false;
+       return err;
+}
+
+static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       bool radio_state;
+       bool blocked;
+       u8 valid = 0;
+
+       if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+               return;
+
+       mutex_lock(&rtlpriv->locks.conf_mutex);
+
+       /*if Radio On return true here */
+       radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+
+       if (valid) {
+               if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
+                       rtlpriv->rfkill.rfkill_state = radio_state;
+
+                       RT_TRACE(COMP_RF, DBG_DMESG,
+                                (KERN_INFO "wireless radio switch turned %s\n",
+                                 radio_state ? "on" : "off"));
+
+                       blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
+                       wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
+               }
+       }
+
+       mutex_unlock(&rtlpriv->locks.conf_mutex);
+}
+
+/* this function is called by mac80211 to flush tx buffer
+ * before switch channle or power save, or tx buffer packet
+ * maybe send after offchannel or rf sleep, this may cause
+ * dis-association by AP */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->intf_ops->flush)
+               rtlpriv->intf_ops->flush(hw, queues, drop);
+}
+#else
+static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->intf_ops->flush)
+               rtlpriv->intf_ops->flush(hw, drop);
+}
+#endif
+
+const struct ieee80211_ops rtl_ops = {
+       .start = rtl_op_start,
+       .stop = rtl_op_stop,
+       .tx = rtl_op_tx,
+       .add_interface = rtl_op_add_interface,
+       .remove_interface = rtl_op_remove_interface,
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+/*<delete in kernel end>*/
+       .change_interface = rtl_op_change_interface,
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+       .config = rtl_op_config,
+       .configure_filter = rtl_op_configure_filter,
+       .set_key = rtl_op_set_key,
+       .conf_tx = rtl_op_conf_tx,
+       .bss_info_changed = rtl_op_bss_info_changed,
+       .get_tsf = rtl_op_get_tsf,
+       .set_tsf = rtl_op_set_tsf,
+       .reset_tsf = rtl_op_reset_tsf,
+       .sta_notify = rtl_op_sta_notify,
+       .ampdu_action = rtl_op_ampdu_action,
+       .sw_scan_start = rtl_op_sw_scan_start,
+       .sw_scan_complete = rtl_op_sw_scan_complete,
+       .rfkill_poll = rtl_op_rfkill_poll,
+       .sta_add = rtl_op_sta_add,
+       .sta_remove = rtl_op_sta_remove,
+       .flush = rtl_op_flush,
+};
diff --git a/drivers/staging/rtl8821ae/core.h b/drivers/staging/rtl8821ae/core.h
new file mode 100644 (file)
index 0000000..4b247db
--- /dev/null
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * Tmis 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.
+ *
+ * Tmis 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
+ * tmis program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * Tme 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_CORE_H__
+#define __RTL_CORE_H__
+
+#define RTL_SUPPORTED_FILTERS          \
+       (FIF_PROMISC_IN_BSS | \
+       FIF_ALLMULTI | FIF_CONTROL | \
+       FIF_OTHER_BSS | \
+       FIF_FCSFAIL | \
+       FIF_BCN_PRBRESP_PROMISC)
+
+#define RTL_SUPPORTED_CTRL_FILTER      0xFF
+
+extern const struct ieee80211_ops rtl_ops;
+#endif
diff --git a/drivers/staging/rtl8821ae/debug.c b/drivers/staging/rtl8821ae/debug.c
new file mode 100644 (file)
index 0000000..cb05122
--- /dev/null
@@ -0,0 +1,988 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * Tmis 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.
+ *
+ * Tmis 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
+ * tmis program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * Tme 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 "wifi.h"
+#include "cam.h"
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+#define GET_INODE_DATA(__node)         PDE_DATA(__node)
+#else
+#define GET_INODE_DATA(__node)         PDE(__node)->data
+#endif
+
+
+void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 i;
+
+       rtlpriv->dbg.global_debuglevel = DBG_DMESG;
+
+       rtlpriv->dbg.global_debugcomponents =
+               COMP_ERR |
+               COMP_FW |
+               COMP_INIT |
+               COMP_RECV |
+               COMP_SEND |
+               COMP_MLME |
+               COMP_SCAN |
+               COMP_INTR |
+               COMP_LED |
+               COMP_SEC |
+               COMP_BEACON |
+               COMP_RATE |
+               COMP_RXDESC |
+               COMP_DIG |
+               COMP_TXAGC |
+               COMP_POWER |
+               COMP_POWER_TRACKING |
+               COMP_BB_POWERSAVING |
+               COMP_SWAS |
+               COMP_RF |
+               COMP_TURBO |
+               COMP_RATR |
+               COMP_CMD |
+               COMP_EASY_CONCURRENT |
+               COMP_EFUSE |
+               COMP_QOS | COMP_MAC80211 | COMP_REGD |
+               COMP_CHAN |
+               COMP_BT_COEXIST |
+               COMP_IQK |
+               0;
+
+       for (i = 0; i < DBGP_TYPE_MAX; i++)
+               rtlpriv->dbg.dbgp_type[i] = 0;
+
+       /*Init Debug flag enable condition */
+}
+
+struct proc_dir_entry *proc_topdir;
+static int rtl_proc_get_mac_0(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i, n, page;
+       int max = 0xff;
+       page = 0x000;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_read_dword(rtlpriv, (page | n)));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_mac_0(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_mac_0, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_mac_0 = {
+       .open = dl_proc_open_mac_0,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_mac_1(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i, n, page;
+       int max = 0xff;
+       page = 0x100;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_read_dword(rtlpriv, (page | n)));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_mac_1(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_mac_1, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_mac_1 = {
+       .open = dl_proc_open_mac_1,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_mac_2(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i, n, page;
+       int max = 0xff;
+       page = 0x200;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_read_dword(rtlpriv, (page | n)));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_mac_2(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_mac_2, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_mac_2 = {
+       .open = dl_proc_open_mac_2,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_mac_3(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i, n, page;
+       int max = 0xff;
+       page = 0x300;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_read_dword(rtlpriv, (page | n)));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_mac_3(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_mac_3, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_mac_3 = {
+       .open = dl_proc_open_mac_3,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_mac_4(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i, n, page;
+       int max = 0xff;
+       page = 0x400;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_read_dword(rtlpriv, (page | n)));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_mac_4(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_mac_4, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_mac_4 = {
+       .open = dl_proc_open_mac_4,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_mac_5(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i, n, page;
+       int max = 0xff;
+       page = 0x500;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_read_dword(rtlpriv, (page | n)));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_mac_5(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_mac_5, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_mac_5 = {
+       .open = dl_proc_open_mac_5,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_mac_6(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i, n, page;
+       int max = 0xff;
+       page = 0x600;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_read_dword(rtlpriv, (page | n)));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_mac_6(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_mac_6, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_mac_6 = {
+       .open = dl_proc_open_mac_6,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_mac_7(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i, n, page;
+       int max = 0xff;
+       page = 0x700;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_read_dword(rtlpriv, (page | n)));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_mac_7(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_mac_7, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_mac_7 = {
+       .open = dl_proc_open_mac_7,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_bb_8(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n, page;
+       int max = 0xff;
+       page = 0x800;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_bbreg(hw, (page | n), 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_bb_8(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_bb_8, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_bb_8 = {
+       .open = dl_proc_open_bb_8,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_bb_9(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n, page;
+       int max = 0xff;
+       page = 0x900;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_bbreg(hw, (page | n), 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_bb_9(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_bb_9, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_bb_9 = {
+       .open = dl_proc_open_bb_9,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_bb_a(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n, page;
+       int max = 0xff;
+       page = 0xa00;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_bbreg(hw, (page | n), 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_bb_a(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_bb_a, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_bb_a = {
+       .open = dl_proc_open_bb_a,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_bb_b(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n, page;
+       int max = 0xff;
+       page = 0xb00;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_bbreg(hw, (page | n), 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_bb_b(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_bb_b, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_bb_b = {
+       .open = dl_proc_open_bb_b,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_bb_c(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n, page;
+       int max = 0xff;
+       page = 0xc00;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_bbreg(hw, (page | n), 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_bb_c(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_bb_c, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_bb_c = {
+       .open = dl_proc_open_bb_c,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_bb_d(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n, page;
+       int max = 0xff;
+       page = 0xd00;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_bbreg(hw, (page | n), 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_bb_d(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_bb_d, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_bb_d = {
+       .open = dl_proc_open_bb_d,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_bb_e(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n, page;
+       int max = 0xff;
+       page = 0xe00;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_bbreg(hw, (page | n), 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_bb_e(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_bb_e, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_bb_e = {
+       .open = dl_proc_open_bb_e,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_bb_f(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n, page;
+       int max = 0xff;
+       page = 0xf00;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n + page);
+               for (i = 0; i < 4 && n <= max; i++, n += 4)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_bbreg(hw, (page | n), 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_bb_f(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_bb_f, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_bb_f = {
+       .open = dl_proc_open_bb_f,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_reg_rf_a(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n;
+       int max = 0x40;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n);
+               for (i = 0; i < 4 && n <= max; n += 1, i++)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_rfreg(hw, RF90_PATH_A, n, 0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_rf_a(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_reg_rf_a, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_rf_a = {
+       .open = dl_proc_open_rf_a,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_reg_rf_b(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       int i, n;
+       int max = 0x40;
+
+       for (n = 0; n <= max; ) {
+               seq_printf(m, "\n%8.8x  ", n);
+               for (i = 0; i < 4 && n <= max; n += 1, i++)
+                       seq_printf(m, "%8.8x    ",
+                                  rtl_get_rfreg(hw, RF90_PATH_B, n,
+                                                0xffffffff));
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_rf_b(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_reg_rf_b, GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_rf_b = {
+       .open = dl_proc_open_rf_b,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_cam_register_1(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 target_cmd = 0;
+       u32 target_val=0;
+       u8 entry_i=0;
+       u32 ulstatus;
+       int i = 100, j = 0;
+
+       /* This dump the current register page */
+       seq_puts(m,
+           "\n#################### SECURITY CAM (0-10) ##################\n ");
+
+       for (j = 0; j < 11; j++) {
+               seq_printf(m, "\nD:  %2x > ", j);
+               for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+                       /* polling bit, and No Write enable, and address  */
+                       target_cmd = entry_i + CAM_CONTENT_COUNT * j;
+                       target_cmd = target_cmd | BIT(31);
+
+                       /* Check polling bit is clear */
+                       while ((i--) >= 0) {
+                               ulstatus = rtl_read_dword(rtlpriv,
+                                               rtlpriv->cfg->maps[RWCAM]);
+                               if (ulstatus & BIT(31)) {
+                                       continue;
+                               } else {
+                                       break;
+                               }
+                       }
+
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+                                       target_cmd);
+                       target_val = rtl_read_dword(rtlpriv,
+                                                   rtlpriv->cfg->maps[RCAMO]);
+                       seq_printf(m, "%8.8x ", target_val);
+               }
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_cam_1(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_cam_register_1,
+                          GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_cam_1 = {
+       .open = dl_proc_open_cam_1,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_cam_register_2(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 target_cmd = 0;
+       u32 target_val = 0;
+       u8 entry_i = 0;
+       u32 ulstatus;
+       int i = 100, j = 0;
+
+       /* This dump the current register page */
+       seq_puts(m,
+           "\n################### SECURITY CAM (11-21) ##################\n ");
+
+       for (j = 11; j < 22; j++) {
+               seq_printf(m, "\nD:  %2x > ", j);
+               for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+                       target_cmd = entry_i + CAM_CONTENT_COUNT * j;
+                       target_cmd = target_cmd | BIT(31);
+
+                       while ((i--) >= 0) {
+                               ulstatus = rtl_read_dword(rtlpriv,
+                                               rtlpriv->cfg->maps[RWCAM]);
+                               if (ulstatus & BIT(31)) {
+                                       continue;
+                               } else {
+                                       break;
+                               }
+                       }
+
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+                                       target_cmd);
+                       target_val = rtl_read_dword(rtlpriv,
+                                                   rtlpriv->cfg->maps[RCAMO]);
+                       seq_printf(m, "%8.8x ", target_val);
+               }
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_cam_2(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_cam_register_2,
+                          GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_cam_2 = {
+       .open = dl_proc_open_cam_2,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+static int rtl_proc_get_cam_register_3(struct seq_file *m, void *v)
+{
+       struct ieee80211_hw *hw = m->private;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 target_cmd = 0;
+       u32 target_val = 0;
+       u8 entry_i = 0;
+       u32 ulstatus;
+       int i = 100, j = 0;
+
+       /* This dump the current register page */
+       seq_puts(m,
+           "\n################### SECURITY CAM (22-31) ##################\n ");
+
+       for (j = 22; j < TOTAL_CAM_ENTRY; j++) {
+               seq_printf(m, "\nD:  %2x > ", j);
+               for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+                       target_cmd = entry_i+CAM_CONTENT_COUNT*j;
+                       target_cmd = target_cmd | BIT(31);
+
+                       while ((i--) >= 0) {
+                               ulstatus = rtl_read_dword(rtlpriv,
+                                               rtlpriv->cfg->maps[RWCAM]);
+                               if (ulstatus & BIT(31)) {
+                                       continue;
+                               } else {
+                                       break;
+                               }
+                       }
+
+                       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
+                                       target_cmd);
+                       target_val = rtl_read_dword(rtlpriv,
+                                                   rtlpriv->cfg->maps[RCAMO]);
+                       seq_printf(m, "%8.8x ", target_val);
+               }
+       }
+       seq_puts(m, "\n");
+       return 0;
+}
+
+static int dl_proc_open_cam_3(struct inode *inode, struct file *file)
+{
+       return single_open(file, rtl_proc_get_cam_register_3,
+                          GET_INODE_DATA(inode));
+}
+
+static const struct file_operations file_ops_cam_3 = {
+       .open = dl_proc_open_cam_3,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
+
+void rtl_proc_add_one(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct proc_dir_entry *entry;
+
+       snprintf(rtlpriv->dbg.proc_name, 18, "%x-%x-%x-%x-%x-%x",
+               rtlefuse->dev_addr[0], rtlefuse->dev_addr[1],
+               rtlefuse->dev_addr[2], rtlefuse->dev_addr[3],
+               rtlefuse->dev_addr[4], rtlefuse->dev_addr[5]);
+
+       rtlpriv->dbg.proc_dir = proc_mkdir(rtlpriv->dbg.proc_name, proc_topdir);
+       if (!rtlpriv->dbg.proc_dir) {
+               RT_TRACE(COMP_INIT, DBG_EMERG, ("Unable to init "
+                       "/proc/net/%s/%s\n", rtlpriv->cfg->name,
+                       rtlpriv->dbg.proc_name));
+               return;
+       }
+
+       entry = proc_create_data("mac-0", S_IFREG | S_IRUGO,
+                                 rtlpriv->dbg.proc_dir, &file_ops_mac_0, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, DBG_EMERG,
+                        ("Unable to initialize /proc/net/%s/%s/mac-0\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("mac-1", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_mac_1, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/mac-1\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("mac-2", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_mac_2, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/mac-2\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("mac-3", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_mac_3, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/mac-3\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("mac-4", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_mac_4, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/mac-4\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("mac-5", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_mac_5, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/mac-5\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("mac-6", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_mac_6, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/mac-6\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("mac-7", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_mac_7, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/mac-7\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("bb-8", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_bb_8, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/bb-8\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("bb-9", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_bb_9, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/bb-9\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("bb-a", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_bb_a, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/bb-a\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("bb-b", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_bb_b, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/bb-b\n",
+                     rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("bb-c", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_bb_c, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/bb-c\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("bb-d", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_bb_d, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/bb-d\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("bb-e", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_bb_e, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/bb-e\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("bb-f", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_bb_f, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/bb-f\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("rf-a", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_rf_a, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/rf-a\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("rf-b", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_rf_b, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/rf-b\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("cam-1", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_cam_1, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/cam-1\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("cam-2", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_cam_2, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/cam-2\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+
+       entry = proc_create_data("cam-3", S_IFREG | S_IRUGO,
+                                rtlpriv->dbg.proc_dir, &file_ops_cam_3, hw);
+       if (!entry)
+               RT_TRACE(COMP_INIT, COMP_ERR,
+                        ("Unable to initialize /proc/net/%s/%s/cam-3\n",
+                         rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
+}
+
+void rtl_proc_remove_one(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->dbg.proc_dir) {
+               remove_proc_entry("mac-0", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("mac-1", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("mac-2", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("mac-3", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("mac-4", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("mac-5", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("mac-6", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("mac-7", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("bb-8", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("bb-9", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("bb-a", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("bb-b", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("bb-c", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("bb-d", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("bb-e", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("bb-f", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("rf-a", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("rf-b", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("cam-1", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("cam-2", rtlpriv->dbg.proc_dir);
+               remove_proc_entry("cam-3", rtlpriv->dbg.proc_dir);
+
+               remove_proc_entry(rtlpriv->dbg.proc_name, proc_topdir);
+
+               rtlpriv->dbg.proc_dir = NULL;
+       }
+}
+
+void rtl_proc_add_topdir(void)
+{
+       proc_topdir = proc_mkdir("rtlwifi", init_net.proc_net);
+}
+
+void rtl_proc_remove_topdir(void)
+{
+       if (proc_topdir)
+               remove_proc_entry("rtlwifi", init_net.proc_net);
+}
\ No newline at end of file
diff --git a/drivers/staging/rtl8821ae/debug.h b/drivers/staging/rtl8821ae/debug.h
new file mode 100644 (file)
index 0000000..5eb6251
--- /dev/null
@@ -0,0 +1,227 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * Tmis 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.
+ *
+ * Tmis 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
+ * tmis program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * Tme 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_DEBUG_H__
+#define __RTL_DEBUG_H__
+
+/*--------------------------------------------------------------
+                       Debug level
+--------------------------------------------------------------*/
+/*
+ *Fatal bug.
+ *For example, Tx/Rx/IO locked up,
+ *memory access violation,
+ *resource allocation failed,
+ *unexpected HW behavior, HW BUG
+ *and so on.
+ */
+#define DBG_EMERG                      0
+
+/*
+ *Abnormal, rare, or unexpeted cases.
+ *For example, Packet/IO Ctl canceled,
+ *device suprisely unremoved and so on.
+ */
+#define        DBG_WARNING                     2
+
+/*
+ *Normal case driver developer should
+ *open, we can see link status like
+ *assoc/AddBA/DHCP/adapter start and
+ *so on basic and useful infromations.
+ */
+#define DBG_DMESG                      3
+
+/*
+ *Normal case with useful information
+ *about current SW or HW state.
+ *For example, Tx/Rx descriptor to fill,
+ *Tx/Rx descriptor completed status,
+ *SW protocol state change, dynamic
+ *mechanism state change and so on.
+ */
+#define DBG_LOUD                       4
+
+/*
+ *Normal case with detail execution
+ *flow or information.
+ */
+#define        DBG_TRACE                       5
+
+/*--------------------------------------------------------------
+               Define the rt_trace components
+--------------------------------------------------------------*/
+#define COMP_ERR                       BIT(0)
+#define COMP_FW                                BIT(1)
+#define COMP_INIT                      BIT(2)  /*For init/deinit */
+#define COMP_RECV                      BIT(3)  /*For Rx. */
+#define COMP_SEND                      BIT(4)  /*For Tx. */
+#define COMP_MLME                      BIT(5)  /*For MLME. */
+#define COMP_SCAN                      BIT(6)  /*For Scan. */
+#define COMP_INTR                      BIT(7)  /*For interrupt Related. */
+#define COMP_LED                       BIT(8)  /*For LED. */
+#define COMP_SEC                       BIT(9)  /*For sec. */
+#define COMP_BEACON                    BIT(10) /*For beacon. */
+#define COMP_RATE                      BIT(11) /*For rate. */
+#define COMP_RXDESC                    BIT(12) /*For rx desc. */
+#define COMP_DIG                       BIT(13) /*For DIG */
+#define COMP_TXAGC                     BIT(14) /*For Tx power */
+#define COMP_HIPWR                     BIT(15) /*For High Power Mechanism */
+#define COMP_POWER                     BIT(16) /*For lps/ips/aspm. */
+#define COMP_POWER_TRACKING    BIT(17) /*For TX POWER TRACKING */
+#define COMP_BB_POWERSAVING    BIT(18)
+#define COMP_SWAS                      BIT(19) /*For SW Antenna Switch */
+#define COMP_RF                                BIT(20) /*For RF. */
+#define COMP_TURBO                     BIT(21) /*For EDCA TURBO. */
+#define COMP_RATR                      BIT(22)
+#define COMP_CMD                       BIT(23)
+#define COMP_EFUSE                     BIT(24)
+#define COMP_QOS                       BIT(25)
+#define COMP_MAC80211          BIT(26)
+#define COMP_REGD                      BIT(27)
+#define COMP_CHAN                      BIT(28)
+#define COMP_EASY_CONCURRENT           BIT(29)
+#define COMP_BT_COEXIST                        BIT(30)
+#define COMP_IQK                       BIT(31)
+
+/*--------------------------------------------------------------
+               Define the rt_print components
+--------------------------------------------------------------*/
+/* Define EEPROM and EFUSE  check module bit*/
+#define EEPROM_W                       BIT(0)
+#define EFUSE_PG                       BIT(1)
+#define EFUSE_READ_ALL         BIT(2)
+
+/* Define init check for module bit*/
+#define        INIT_EEPROM                     BIT(0)
+#define        INIT_TxPower            BIT(1)
+#define        INIT_IQK                        BIT(2)
+#define        INIT_RF                         BIT(3)
+
+/* Define PHY-BB/RF/MAC check module bit */
+#define        PHY_BBR                         BIT(0)
+#define        PHY_BBW                         BIT(1)
+#define        PHY_RFR                         BIT(2)
+#define        PHY_RFW                         BIT(3)
+#define        PHY_MACR                        BIT(4)
+#define        PHY_MACW                        BIT(5)
+#define        PHY_ALLR                        BIT(6)
+#define        PHY_ALLW                        BIT(7)
+#define        PHY_TXPWR                       BIT(8)
+#define        PHY_PWRDIFF                     BIT(9)
+
+/* Define Dynamic Mechanism check module bit --> FDM */
+#define WA_IOT                         BIT(0)
+#define DM_PWDB                                BIT(1)
+#define DM_MONITOR                     BIT(2)
+#define DM_DIG                         BIT(3)
+#define DM_EDCA_TURBO          BIT(4)
+
+enum dbgp_flag_e {
+       FQOS = 0,
+       FTX = 1,
+       FRX = 2,
+       FSEC = 3,
+       FMGNT = 4,
+       FMLME = 5,
+       FRESOURCE = 6,
+       FBEACON = 7,
+       FISR = 8,
+       FPHY = 9,
+       FMP = 10,
+       FEEPROM = 11,
+       FPWR = 12,
+       FDM = 13,
+       FDBGCtrl = 14,
+       FC2H = 15,
+       FBT = 16,
+       FINIT = 17,
+       FIOCTL = 18,
+       DBGP_TYPE_MAX
+};
+
+#define RT_ASSERT(_exp,fmt)                            \
+       do { \
+               if(!(_exp))     {                       \
+                       printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \
+                       __func__);      \
+                       printk fmt;                     \
+               } \
+       } while(0);
+
+#define        RT_DISP(dbgtype, dbgflag, printstr)
+
+#define RT_TRACE(comp, level, fmt)\
+       do { \
+               if(unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \
+                       ((level) <= rtlpriv->dbg.global_debuglevel))) {\
+                       printk(KERN_DEBUG "%s-%d:%s():<%lx-%x> ", \
+                       KBUILD_MODNAME, \
+                       rtlpriv->rtlhal.interfaceindex, __func__, \
+                       in_interrupt(), in_atomic());   \
+                       printk fmt;                     \
+               }\
+       } while(0);
+
+#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr)   \
+       do {                                            \
+               if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \
+                       printk(KERN_DEBUG "%s: ", KBUILD_MODNAME);      \
+                       printk printstr;                \
+               }                                       \
+       } while(0);
+
+#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
+               _hexdatalen) \
+       do {\
+               if(unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents ) &&\
+                       (_level <= rtlpriv->dbg.global_debuglevel )))   { \
+                       int __i;                                        \
+                       u8*     ptr = (u8*)_hexdata;                    \
+                       printk(KERN_DEBUG "%s: ", KBUILD_MODNAME);      \
+                       printk(KERN_DEBUG "In process \"%s\" (pid %i):", \
+                                       current->comm,  \
+                                       current->pid); \
+                       printk(_titlestring);           \
+                       for( __i=0; __i<(int)_hexdatalen; __i++ ) {     \
+                               printk("%02X%s", ptr[__i], (((__i + 1) % 4) \
+                                                       == 0)?"  ":" ");\
+                               if (((__i + 1) % 16) == 0)      \
+                                       printk("\n");   \
+                       }                               \
+                       printk(KERN_DEBUG "\n");                        \
+               } \
+       } while(0);
+
+void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
+void rtl_proc_add_one(struct ieee80211_hw *hw);
+void rtl_proc_remove_one(struct ieee80211_hw *hw);
+void rtl_proc_add_topdir(void);
+void rtl_proc_remove_topdir(void);
+#endif
diff --git a/drivers/staging/rtl8821ae/efuse.c b/drivers/staging/rtl8821ae/efuse.c
new file mode 100644 (file)
index 0000000..74c19ec
--- /dev/null
@@ -0,0 +1,1285 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * Tmis 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.
+ *
+ * Tmis 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
+ * tmis program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * Tme 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 "wifi.h"
+#include "efuse.h"
+#include "btcoexist/halbt_precomp.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+#include <linux/export.h>
+#endif
+
+static const u8 MAX_PGPKT_SIZE = 9;
+static const u8 PGPKT_DATA_SIZE = 8;
+static const int EFUSE_MAX_SIZE = 512;
+
+static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
+       {0, 0, 0, 2},
+       {0, 1, 0, 2},
+       {0, 2, 0, 2},
+       {1, 0, 0, 1},
+       {1, 0, 1, 1},
+       {1, 1, 0, 1},
+       {1, 1, 1, 3},
+       {1, 3, 0, 17},
+       {3, 3, 1, 48},
+       {10, 0, 0, 6},
+       {10, 3, 0, 1},
+       {10, 3, 1, 1},
+       {11, 0, 0, 28}
+};
+
+static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
+                                   u8 * value);
+static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
+                                   u16 * value);
+static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset,
+                                   u32 * value);
+static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset,
+                                    u8 value);
+static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset,
+                                    u16 value);
+static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
+                                    u32 value);
+static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
+                               u8 data);
+static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse);
+static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
+                               u8 *data);
+static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
+                                u8 word_en, u8 * data);
+static void efuse_word_enable_data_read(u8 word_en, u8 * sourdata,
+                                       u8 * targetdata);
+static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
+                                      u16 efuse_addr, u8 word_en, u8 * data);
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite,
+                                       u8 pwrstate);
+static u16 efuse_get_current_size(struct ieee80211_hw *hw);
+static u8 efuse_calculate_word_cnts(u8 word_en);
+
+void efuse_initialize(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 bytetemp;
+       u8 temp;
+
+       bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1);
+       temp = bytetemp | 0x20;
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp);
+
+       bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1);
+       temp = bytetemp & 0xFE;
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp);
+
+       bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
+       temp = bytetemp | 0x80;
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp);
+
+       rtl_write_byte(rtlpriv, 0x2F8, 0x3);
+
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
+
+}
+
+u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 data;
+       u8 bytetemp;
+       u8 temp;
+       u32 k = 0;
+       const u32 efuse_real_content_len =
+               rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
+
+       if (address < efuse_real_content_len) {
+               temp = address & 0xFF;
+               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+                              temp);
+               bytetemp = rtl_read_byte(rtlpriv,
+                                        rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+               temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
+               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+                              temp);
+
+               bytetemp = rtl_read_byte(rtlpriv,
+                                        rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+               temp = bytetemp & 0x7F;
+               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
+                              temp);
+
+               bytetemp = rtl_read_byte(rtlpriv,
+                                        rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+               while (!(bytetemp & 0x80)) {
+                       bytetemp = rtl_read_byte(rtlpriv,
+                                                rtlpriv->cfg->
+                                                maps[EFUSE_CTRL] + 3);
+                       k++;
+                       if (k == 1000) {
+                               k = 0;
+                               break;
+                       }
+               }
+               data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+               return data;
+       } else
+               return 0xFF;
+
+}
+//EXPORT_SYMBOL(efuse_read_1byte);
+
+void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 bytetemp;
+       u8 temp;
+       u32 k = 0;
+       const u32 efuse_real_content_len =
+               rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
+
+       RT_TRACE(COMP_EFUSE, DBG_LOUD,
+                ("Addr=%x Data =%x\n", address, value));
+
+       if (address < efuse_real_content_len) {
+               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
+
+               temp = address & 0xFF;
+               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+                              temp);
+               bytetemp = rtl_read_byte(rtlpriv,
+                                        rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+
+               temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
+               rtl_write_byte(rtlpriv,
+                              rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp);
+
+               bytetemp = rtl_read_byte(rtlpriv,
+                                        rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+               temp = bytetemp | 0x80;
+               rtl_write_byte(rtlpriv,
+                              rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp);
+
+               bytetemp = rtl_read_byte(rtlpriv,
+                                        rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+
+               while (bytetemp & 0x80) {
+                       bytetemp = rtl_read_byte(rtlpriv,
+                                                rtlpriv->cfg->
+                                                maps[EFUSE_CTRL] + 3);
+                       k++;
+                       if (k == 100) {
+                               k = 0;
+                               break;
+                       }
+               }
+       }
+
+}
+
+void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 value32;
+       u8 readbyte;
+       u16 retry;
+
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+                      (_offset & 0xff));
+       readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+                      ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
+
+       readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
+                      (readbyte & 0x7f));
+
+       retry = 0;
+       value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+       while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
+               value32 = rtl_read_dword(rtlpriv,
+                                        rtlpriv->cfg->maps[EFUSE_CTRL]);
+               retry++;
+       }
+
+       udelay(50);
+       value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+
+       *pbuf = (u8) (value32 & 0xff);
+}
+
+void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 efuse_tbl[rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]];
+       u8 rtemp8[1];
+       u16 efuse_addr = 0;
+       u8 offset, wren;
+       u8 u1temp = 0;
+       u16 i;
+       u16 j;
+       const u16 efuse_max_section =
+               rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
+       const u32 efuse_real_content_len =
+               rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
+       u16 efuse_word[efuse_max_section][EFUSE_MAX_WORD_UNIT];
+       u16 efuse_utilized = 0;
+       u8 efuse_usage;
+
+       if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
+               RT_TRACE(COMP_EFUSE, DBG_LOUD,
+                        ("read_efuse(): Invalid offset(%#x) with read "
+                         "bytes(%#x)!!\n", _offset, _size_byte));
+               return;
+       }
+
+       for (i = 0; i < efuse_max_section; i++)
+               for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
+                       efuse_word[i][j] = 0xFFFF;
+
+       read_efuse_byte(hw, efuse_addr, rtemp8);
+       if (*rtemp8 != 0xFF) {
+               efuse_utilized++;
+               RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+                       ("Addr=%d\n", efuse_addr));
+               efuse_addr++;
+       }
+
+       while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_real_content_len)) {
+               /*  Check PG header for section num.  */
+               if((*rtemp8 & 0x1F ) == 0x0F) {/* extended header */
+                       u1temp =( (*rtemp8 & 0xE0) >> 5);
+                       read_efuse_byte(hw, efuse_addr, rtemp8);
+
+                       if((*rtemp8 & 0x0F) == 0x0F) {
+                               efuse_addr++;
+                               read_efuse_byte(hw, efuse_addr, rtemp8);
+
+                               if (*rtemp8 != 0xFF &&
+                                   (efuse_addr < efuse_real_content_len)) {
+                                       efuse_addr++;
+                               }
+                               continue;
+                       } else {
+                               offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
+                               wren = (*rtemp8 & 0x0F);
+                               efuse_addr++;
+                       }
+               } else {
+                       offset = ((*rtemp8 >> 4) & 0x0f);
+                       wren = (*rtemp8 & 0x0f);
+               }
+
+               if (offset < efuse_max_section) {
+                       RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+                               ("offset-%d Worden=%x\n", offset, wren));
+
+                       for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+                               if (!(wren & 0x01)) {
+                                       RTPRINT(rtlpriv, FEEPROM,
+                                               EFUSE_READ_ALL, ("Addr=%d\n",
+                                                                efuse_addr));
+
+                                       read_efuse_byte(hw, efuse_addr, rtemp8);
+                                       efuse_addr++;
+                                       efuse_utilized++;
+                                       efuse_word[offset][i] = (*rtemp8 &
+                                                                0xff);
+
+                                       if (efuse_addr >=
+                                           efuse_real_content_len)
+                                               break;
+
+                                       RTPRINT(rtlpriv, FEEPROM,
+                                               EFUSE_READ_ALL, ("Addr=%d\n",
+                                                                efuse_addr));
+
+                                       read_efuse_byte(hw, efuse_addr, rtemp8);
+                                       efuse_addr++;
+                                       efuse_utilized++;
+                                       efuse_word[offset][i] |=
+                                           (((u16) * rtemp8 << 8) & 0xff00);
+
+                                       if (efuse_addr >= efuse_real_content_len)
+                                               break;
+                               }
+
+                               wren >>= 1;
+                       }
+               }
+
+               RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
+                       ("Addr=%d\n", efuse_addr));
+               read_efuse_byte(hw, efuse_addr, rtemp8);
+               if (*rtemp8 != 0xFF && (efuse_addr < efuse_real_content_len)) {
+                       efuse_utilized++;
+                       efuse_addr++;
+               }
+       }
+
+       for (i = 0; i < efuse_max_section; i++) {
+               for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
+                       efuse_tbl[(i * 8) + (j * 2)] =
+                           (efuse_word[i][j] & 0xff);
+                       efuse_tbl[(i * 8) + ((j * 2) + 1)] =
+                           ((efuse_word[i][j] >> 8) & 0xff);
+               }
+       }
+
+       for (i = 0; i < _size_byte; i++)
+               pbuf[i] = efuse_tbl[_offset + i];
+
+       rtlefuse->efuse_usedbytes = efuse_utilized;
+       efuse_usage = (u8) ((efuse_utilized * 100) / efuse_real_content_len);
+       rtlefuse->efuse_usedpercentage = efuse_usage;
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
+                                     (u8 *) & efuse_utilized);
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
+                                     (u8 *) & efuse_usage);
+}
+
+bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 section_idx, i, Base;
+       u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
+       bool bwordchanged, bresult = true;
+
+       for (section_idx = 0; section_idx < 16; section_idx++) {
+               Base = section_idx * 8;
+               bwordchanged = false;
+
+               for (i = 0; i < 8; i = i + 2) {
+                       if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
+                            rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i]) ||
+                           (rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i + 1] !=
+                            rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
+                                                                  1])) {
+                               words_need++;
+                               bwordchanged = true;
+                       }
+               }
+
+               if (bwordchanged == true)
+                       hdr_num++;
+       }
+
+       totalbytes = hdr_num + words_need * 2;
+       efuse_used = rtlefuse->efuse_usedbytes;
+
+       if ((totalbytes + efuse_used) >= (EFUSE_MAX_SIZE -
+               rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))
+               bresult = false;
+
+       RT_TRACE(COMP_EFUSE, DBG_LOUD,
+                ("efuse_shadow_update_chk(): totalbytes(%#x), "
+                 "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
+                 totalbytes, hdr_num, words_need, efuse_used));
+
+       return bresult;
+}
+
+void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
+                      u16 offset, u32 *value)
+{
+       if (type == 1)
+               efuse_shadow_read_1byte(hw, offset, (u8 *) value);
+       else if (type == 2)
+               efuse_shadow_read_2byte(hw, offset, (u16 *) value);
+       else if (type == 4)
+               efuse_shadow_read_4byte(hw, offset, (u32 *) value);
+
+}
+
+void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
+                               u32 value)
+{
+       if (type == 1)
+               efuse_shadow_write_1byte(hw, offset, (u8) value);
+       else if (type == 2)
+               efuse_shadow_write_2byte(hw, offset, (u16) value);
+       else if (type == 4)
+               efuse_shadow_write_4byte(hw, offset, (u32) value);
+
+}
+
+bool efuse_shadow_update(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u16 i, offset, base;
+       u8 word_en = 0x0F;
+       u8 first_pg = false;
+
+       RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n"));
+
+       if (!efuse_shadow_update_chk(hw)) {
+               efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+               memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+                      &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+                      rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+
+               RT_TRACE(COMP_EFUSE, DBG_LOUD,
+                        ("efuse out of capacity!!\n"));
+               return false;
+       }
+       efuse_power_switch(hw, true, true);
+
+       for (offset = 0; offset < 16; offset++) {
+
+               word_en = 0x0F;
+               base = offset * 8;
+
+               for (i = 0; i < 8; i++) {
+                       if (first_pg == true) {
+
+                               word_en &= ~(BIT(i / 2));
+
+                               rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
+                                   rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
+                       } else {
+
+                               if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
+                                   rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) {
+                                       word_en &= ~(BIT(i / 2));
+
+                                       rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
+                                           rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
+                               }
+                       }
+               }
+
+               if (word_en != 0x0F) {
+                       u8 tmpdata[8];
+                       memcpy(tmpdata, (&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base]), 8);
+                       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
+                                     ("U-efuse\n"), tmpdata, 8);
+
+                       if (!efuse_pg_packet_write(hw, (u8) offset, word_en,
+                                                  tmpdata)) {
+                               RT_TRACE(COMP_ERR, DBG_WARNING,
+                                        ("PG section(%#x) fail!!\n", offset));
+                               break;
+                       }
+               }
+
+       }
+
+       efuse_power_switch(hw, true, false);
+       efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+
+       memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+              &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+              rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+
+       RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n"));
+       return true;
+}
+
+void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+       if (rtlefuse->autoload_failflag == true) {
+               memset((&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]),
+                       0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+       } else {
+               efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
+       }
+
+       memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
+                       &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+                       rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+
+}
+//EXPORT_SYMBOL(rtl_efuse_shadow_map_update);
+
+void efuse_force_write_vendor_Id(struct ieee80211_hw *hw)
+{
+       u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
+
+       efuse_power_switch(hw, true, true);
+
+       efuse_pg_packet_write(hw, 1, 0xD, tmpdata);
+
+       efuse_power_switch(hw, true, false);
+
+}
+
+void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
+{
+}
+
+static void efuse_shadow_read_1byte(struct ieee80211_hw *hw,
+                                   u16 offset, u8 *value)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+}
+
+static void efuse_shadow_read_2byte(struct ieee80211_hw *hw,
+                                   u16 offset, u16 *value)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+       *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+       *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
+
+}
+
+static void efuse_shadow_read_4byte(struct ieee80211_hw *hw,
+                                   u16 offset, u32 *value)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+       *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
+       *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
+       *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16;
+       *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24;
+}
+
+static void efuse_shadow_write_1byte(struct ieee80211_hw *hw,
+                                    u16 offset, u8 value)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+       rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value;
+}
+
+static void efuse_shadow_write_2byte(struct ieee80211_hw *hw,
+                                    u16 offset, u16 value)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+       rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF;
+       rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8;
+
+}
+
+static void efuse_shadow_write_4byte(struct ieee80211_hw *hw,
+                                    u16 offset, u32 value)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+       rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] =
+           (u8) (value & 0x000000FF);
+       rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] =
+           (u8) ((value >> 8) & 0x0000FF);
+       rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] =
+           (u8) ((value >> 16) & 0x00FF);
+       rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] =
+           (u8) ((value >> 24) & 0xFF);
+
+}
+
+int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmpidx = 0;
+       int bresult;
+
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
+                      (u8) (addr & 0xff));
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+                      ((u8) ((addr >> 8) & 0x03)) |
+                      (rtl_read_byte(rtlpriv,
+                                     rtlpriv->cfg->maps[EFUSE_CTRL] + 2) &
+                       0xFC));
+
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
+
+       while (!(0x80 & rtl_read_byte(rtlpriv,
+                                     rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
+              && (tmpidx < 100)) {
+               tmpidx++;
+       }
+
+       if (tmpidx < 100) {
+               *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
+               bresult = true;
+       } else {
+               *data = 0xff;
+               bresult = false;
+       }
+       return bresult;
+}
+//EXPORT_SYMBOL(efuse_one_byte_read);
+
+static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmpidx = 0;
+       bool bresult;
+
+       RT_TRACE(COMP_EFUSE, DBG_LOUD,
+                ("Addr = %x Data=%x\n", addr, data));
+
+       rtl_write_byte(rtlpriv,
+                      rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
+                      (rtl_read_byte(rtlpriv,
+                        rtlpriv->cfg->maps[EFUSE_CTRL] +
+                        2) & 0xFC) | (u8) ((addr >> 8) & 0x03));
+
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data);
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2);
+
+       while ((0x80 & rtl_read_byte(rtlpriv,
+                                    rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
+              && (tmpidx < 100)) {
+               tmpidx++;
+       }
+
+       if (tmpidx < 100)
+               bresult = true;
+       else
+               bresult = false;
+
+       return bresult;
+}
+
+static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       efuse_power_switch(hw, false, true);
+       read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
+       efuse_power_switch(hw, false, false);
+}
+
+static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
+                               u8 efuse_data, u8 offset, u8 *tmpdata,
+                               u8 *readstate)
+{
+       bool bdataempty = true;
+       u8 hoffset;
+       u8 tmpidx;
+       u8 hworden;
+       u8 word_cnts;
+
+       hoffset = (efuse_data >> 4) & 0x0F;
+       hworden = efuse_data & 0x0F;
+       word_cnts = efuse_calculate_word_cnts(hworden);
+
+       if (hoffset == offset) {
+               for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
+                       if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
+                                               &efuse_data)) {
+                               tmpdata[tmpidx] = efuse_data;
+                               if (efuse_data != 0xff)
+                                       bdataempty = true;
+                       }
+               }
+
+               if (bdataempty == true) {
+                       *readstate = PG_STATE_DATA;
+               } else {
+                       *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
+                       *readstate = PG_STATE_HEADER;
+               }
+
+       } else {
+               *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
+               *readstate = PG_STATE_HEADER;
+       }
+}
+
+static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
+{
+       u8 readstate = PG_STATE_HEADER;
+
+       bool bcontinual = true;
+
+       u8 efuse_data, word_cnts = 0;
+       u16 efuse_addr = 0;
+       u8 hworden = 0;
+       u8 tmpdata[8];
+
+       if (data == NULL)
+               return false;
+       if (offset > 15)
+               return false;
+
+       memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
+       memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
+
+       while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) {
+               if (readstate & PG_STATE_HEADER) {
+                       if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
+                           && (efuse_data != 0xFF))
+                               efuse_read_data_case1(hw, &efuse_addr, efuse_data, offset,
+                                                       tmpdata, &readstate);
+                       else
+                               bcontinual = false;
+               } else if (readstate & PG_STATE_DATA) {
+                       efuse_word_enable_data_read(hworden, tmpdata, data);
+                       efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+                       readstate = PG_STATE_HEADER;
+               }
+
+       }
+
+       if ((data[0] == 0xff) && (data[1] == 0xff) &&
+           (data[2] == 0xff) && (data[3] == 0xff) &&
+           (data[4] == 0xff) && (data[5] == 0xff) &&
+           (data[6] == 0xff) && (data[7] == 0xff))
+               return false;
+       else
+               return true;
+
+}
+
+static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
+                               u8 efuse_data, u8 offset, int *bcontinual,
+                               u8 *write_state, struct pgpkt_struct *target_pkt,
+                               int *repeat_times, int *bresult, u8 word_en)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct pgpkt_struct tmp_pkt;
+       int bdataempty = true;
+       u8 originaldata[8 * sizeof(u8)];
+       u8 badworden = 0x0F;
+       u8 match_word_en, tmp_word_en;
+       u8 tmpindex;
+       u8 tmp_header = efuse_data;
+       u8 tmp_word_cnts;
+
+       tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
+       tmp_pkt.word_en = tmp_header & 0x0F;
+       tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
+
+       if (tmp_pkt.offset != target_pkt->offset) {
+               *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+               *write_state = PG_STATE_HEADER;
+       } else {
+               for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
+                       if (efuse_one_byte_read(hw,
+                                               (*efuse_addr + 1 + tmpindex),
+                                               &efuse_data) && (efuse_data != 0xFF))
+                               bdataempty = false;
+               }
+
+               if (bdataempty == false) {
+                       *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+                       *write_state = PG_STATE_HEADER;
+               } else {
+                       match_word_en = 0x0F;
+                       if (!((target_pkt->word_en & BIT(0)) |
+                           (tmp_pkt.word_en & BIT(0))))
+                               match_word_en &= (~BIT(0));
+
+                       if (!((target_pkt->word_en & BIT(1)) |
+                           (tmp_pkt.word_en & BIT(1))))
+                               match_word_en &= (~BIT(1));
+
+                       if (!((target_pkt->word_en & BIT(2)) |
+                           (tmp_pkt.word_en & BIT(2))))
+                               match_word_en &= (~BIT(2));
+
+                       if (!((target_pkt->word_en & BIT(3)) |
+                           (tmp_pkt.word_en & BIT(3))))
+                               match_word_en &= (~BIT(3));
+
+                       if ((match_word_en & 0x0F) != 0x0F) {
+                               badworden = efuse_word_enable_data_write(hw,
+                                                       *efuse_addr + 1,
+                                                       tmp_pkt.word_en,
+                                                       target_pkt->data);
+
+                               if (0x0F != (badworden & 0x0F)) {
+                                       u8 reorg_offset = offset;
+                                       u8 reorg_worden = badworden;
+                                       efuse_pg_packet_write(hw, reorg_offset,
+                                                             reorg_worden,
+                                                             originaldata);
+                               }
+
+                               tmp_word_en = 0x0F;
+                               if ((target_pkt->word_en & BIT(0)) ^
+                                   (match_word_en & BIT(0)))
+                                       tmp_word_en &= (~BIT(0));
+
+                               if ((target_pkt->word_en & BIT(1)) ^
+                                   (match_word_en & BIT(1)))
+                                       tmp_word_en &= (~BIT(1));
+
+                               if ((target_pkt->word_en & BIT(2)) ^
+                                   (match_word_en & BIT(2)))
+                                       tmp_word_en &= (~BIT(2));
+
+                               if ((target_pkt->word_en & BIT(3)) ^
+                                   (match_word_en & BIT(3)))
+                                       tmp_word_en &= (~BIT(3));
+
+                               if ((tmp_word_en & 0x0F) != 0x0F) {
+                                       *efuse_addr = efuse_get_current_size(hw);
+                                       target_pkt->offset = offset;
+                                       target_pkt->word_en = tmp_word_en;
+                               } else {
+                                       *bcontinual = false;
+                               }
+                               *write_state = PG_STATE_HEADER;
+                               *repeat_times += 1;
+                               if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+                                       *bcontinual = false;
+                                       *bresult = false;
+                               }
+                       } else {
+                               *efuse_addr += (2 * tmp_word_cnts) + 1;
+                               target_pkt->offset = offset;
+                               target_pkt->word_en = word_en;
+                               *write_state = PG_STATE_HEADER;
+                       }
+               }
+       }
+       RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n"));
+}
+
+static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
+                                  int *bcontinual, u8 *write_state,
+                                  struct pgpkt_struct target_pkt,
+                                  int *repeat_times, int *bresult)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct pgpkt_struct tmp_pkt;
+       u8 pg_header;
+       u8 tmp_header;
+       u8 originaldata[8 * sizeof(u8)];
+       u8 tmp_word_cnts;
+       u8 badworden = 0x0F;
+
+       pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en;
+       efuse_one_byte_write(hw, *efuse_addr, pg_header);
+       efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
+
+       if (tmp_header == pg_header) {
+               *write_state = PG_STATE_DATA;
+       } else if (tmp_header == 0xFF) {
+               *write_state = PG_STATE_HEADER;
+               *repeat_times += 1;
+               if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+                       *bcontinual = false;
+                       *bresult = false;
+               }
+       } else {
+               tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
+               tmp_pkt.word_en = tmp_header & 0x0F;
+
+               tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
+
+               memset(originaldata, 0xff,  8 * sizeof(u8));
+
+               if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
+                       badworden = efuse_word_enable_data_write(hw,
+                                                               *efuse_addr + 1,
+                                                               tmp_pkt.word_en,
+                                                               originaldata);
+
+                       if (0x0F != (badworden & 0x0F)) {
+                               u8 reorg_offset = tmp_pkt.offset;
+                               u8 reorg_worden = badworden;
+                               efuse_pg_packet_write(hw, reorg_offset,
+                                                     reorg_worden,
+                                                     originaldata);
+                               *efuse_addr = efuse_get_current_size(hw);
+                       } else {
+                               *efuse_addr = *efuse_addr +
+                                             (tmp_word_cnts * 2) + 1;
+                       }
+               } else {
+                       *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+               }
+
+               *write_state = PG_STATE_HEADER;
+               *repeat_times += 1;
+               if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+                       *bcontinual = false;
+                       *bresult = false;
+               }
+
+               RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+                       ("efuse PG_STATE_HEADER-2\n"));
+       }
+}
+
+static int efuse_pg_packet_write(struct ieee80211_hw *hw,
+                                u8 offset, u8 word_en, u8 *data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct pgpkt_struct target_pkt;
+       u8 write_state = PG_STATE_HEADER;
+       int bcontinual = true, bdataempty = true, bresult = true;
+       u16 efuse_addr = 0;
+       u8 efuse_data;
+       u8 target_word_cnts = 0;
+       u8 badworden = 0x0F;
+       static int repeat_times = 0;
+
+       if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE -
+               rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
+               RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+                       ("efuse_pg_packet_write error \n"));
+               return false;
+       }
+
+       target_pkt.offset = offset;
+       target_pkt.word_en = word_en;
+
+       memset(target_pkt.data, 0xFF,  8 * sizeof(u8));
+
+       efuse_word_enable_data_read(word_en, data, target_pkt.data);
+       target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
+
+       RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
+
+       while (bcontinual && (efuse_addr < (EFUSE_MAX_SIZE -
+               rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) {
+
+               if (write_state == PG_STATE_HEADER) {
+                       bdataempty = true;
+                       badworden = 0x0F;
+                       RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+                               ("efuse PG_STATE_HEADER\n"));
+
+                       if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
+                           (efuse_data != 0xFF))
+                               efuse_write_data_case1(hw, &efuse_addr,
+                                                      efuse_data, offset,
+                                                      &bcontinual,
+                                                      &write_state,
+                                                      &target_pkt,
+                                                      &repeat_times, &bresult,
+                                                      word_en);
+                       else
+                               efuse_write_data_case2(hw, &efuse_addr,
+                                                      &bcontinual,
+                                                      &write_state,
+                                                      target_pkt,
+                                                      &repeat_times,
+                                                      &bresult);
+
+               } else if (write_state == PG_STATE_DATA) {
+                       RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+                               ("efuse PG_STATE_DATA\n"));
+                       badworden = 0x0f;
+                       badworden =
+                           efuse_word_enable_data_write(hw, efuse_addr + 1,
+                                                        target_pkt.word_en,
+                                                        target_pkt.data);
+
+                       if ((badworden & 0x0F) == 0x0F) {
+                               bcontinual = false;
+                       } else {
+                               efuse_addr =
+                                   efuse_addr + (2 * target_word_cnts) + 1;
+
+                               target_pkt.offset = offset;
+                               target_pkt.word_en = badworden;
+                               target_word_cnts =
+                                   efuse_calculate_word_cnts(target_pkt.
+                                                             word_en);
+                               write_state = PG_STATE_HEADER;
+                               repeat_times++;
+                               if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
+                                       bcontinual = false;
+                                       bresult = false;
+                               }
+                               RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
+                                       ("efuse PG_STATE_HEADER-3\n"));
+                       }
+               }
+       }
+
+       if (efuse_addr >= (EFUSE_MAX_SIZE -
+               rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
+               RT_TRACE(COMP_EFUSE, DBG_LOUD,
+                        ("efuse_addr(%#x) Out of size!!\n", efuse_addr));
+       }
+
+       return true;
+}
+
+static void efuse_word_enable_data_read(u8 word_en, u8 * sourdata,
+                                       u8 *targetdata)
+{
+       if (!(word_en & BIT(0))) {
+               targetdata[0] = sourdata[0];
+               targetdata[1] = sourdata[1];
+       }
+
+       if (!(word_en & BIT(1))) {
+               targetdata[2] = sourdata[2];
+               targetdata[3] = sourdata[3];
+       }
+
+       if (!(word_en & BIT(2))) {
+               targetdata[4] = sourdata[4];
+               targetdata[5] = sourdata[5];
+       }
+
+       if (!(word_en & BIT(3))) {
+               targetdata[6] = sourdata[6];
+               targetdata[7] = sourdata[7];
+       }
+}
+
+static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
+                                      u16 efuse_addr, u8 word_en, u8 *data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u16 tmpaddr;
+       u16 start_addr = efuse_addr;
+       u8 badworden = 0x0F;
+       u8 tmpdata[8];
+
+       memset(tmpdata, 0xff, PGPKT_DATA_SIZE);
+       RT_TRACE(COMP_EFUSE, DBG_LOUD,
+                ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr));
+
+       if (!(word_en & BIT(0))) {
+               tmpaddr = start_addr;
+               efuse_one_byte_write(hw, start_addr++, data[0]);
+               efuse_one_byte_write(hw, start_addr++, data[1]);
+
+               efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]);
+               efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]);
+               if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
+                       badworden &= (~BIT(0));
+       }
+
+       if (!(word_en & BIT(1))) {
+               tmpaddr = start_addr;
+               efuse_one_byte_write(hw, start_addr++, data[2]);
+               efuse_one_byte_write(hw, start_addr++, data[3]);
+
+               efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]);
+               efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]);
+               if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
+                       badworden &= (~BIT(1));
+       }
+
+       if (!(word_en & BIT(2))) {
+               tmpaddr = start_addr;
+               efuse_one_byte_write(hw, start_addr++, data[4]);
+               efuse_one_byte_write(hw, start_addr++, data[5]);
+
+               efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]);
+               efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]);
+               if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
+                       badworden &= (~BIT(2));
+       }
+
+       if (!(word_en & BIT(3))) {
+               tmpaddr = start_addr;
+               efuse_one_byte_write(hw, start_addr++, data[6]);
+               efuse_one_byte_write(hw, start_addr++, data[7]);
+
+               efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]);
+               efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]);
+               if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
+                       badworden &= (~BIT(3));
+       }
+
+       return badworden;
+}
+
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 tempval;
+       u16 tmpV16;
+
+       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+       {
+               if (pwrstate == true)
+               {
+                       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69);
+
+                       // 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid
+                       tmpV16 = rtl_read_word(rtlpriv,
+                                              rtlpriv->cfg->maps[SYS_ISO_CTRL]);
+
+                       printk("SYS_ISO_CTRL=%04x.\n",tmpV16);
+                       if( ! (tmpV16 & PWC_EV12V ) ){
+                               tmpV16 |= PWC_EV12V ;
+                                //PlatformEFIOWrite2Byte(pAdapter,REG_SYS_ISO_CTRL,tmpV16);
+                       }
+                       // Reset: 0x0000h[28], default valid
+                       tmpV16 = rtl_read_word(rtlpriv,  rtlpriv->cfg->maps[SYS_FUNC_EN]);
+                       printk("SYS_FUNC_EN=%04x.\n",tmpV16);
+                       if( !(tmpV16 & FEN_ELDR) ){
+                               tmpV16 |= FEN_ELDR ;
+                               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16);
+                       }
+
+                       // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
+                       tmpV16 = rtl_read_word(rtlpriv,  rtlpriv->cfg->maps[SYS_CLK] );
+                       printk("SYS_CLK=%04x.\n",tmpV16);
+                       if( (!(tmpV16 & LOADER_CLK_EN) )  ||(!(tmpV16 & ANA8M) ) )
+                       {
+                               tmpV16 |= (LOADER_CLK_EN |ANA8M ) ;
+                               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_CLK], tmpV16);
+                       }
+
+                       if(bwrite == true)
+                       {
+                               // Enable LDO 2.5V before read/write action
+                               tempval = rtl_read_word(rtlpriv,  rtlpriv->cfg->maps[EFUSE_TEST] + 3);
+                               printk("EFUSE_TEST=%04x.\n",tmpV16);
+                               tempval &= ~(BIT(3) | BIT(4) |BIT(5) | BIT(6));
+                               tempval |= (VOLTAGE_V25 << 3);
+                               tempval |= BIT(7);
+                               rtl_write_byte(rtlpriv,  rtlpriv->cfg->maps[EFUSE_TEST] + 3, tempval);
+                       }
+               }
+               else
+               {
+                       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0x00);
+                       if(bwrite == true){
+                               // Disable LDO 2.5V after read/write action
+                               tempval = rtl_read_word(rtlpriv,  rtlpriv->cfg->maps[EFUSE_TEST] + 3);
+                               rtl_write_byte(rtlpriv,  rtlpriv->cfg->maps[EFUSE_TEST] + 3, (tempval & 0x7F));
+                       }
+               }
+       }
+       else
+       {
+               if (pwrstate == true && (rtlhal->hw_type !=
+                       HARDWARE_TYPE_RTL8192SE)) {
+
+                       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE)
+                               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS],
+                                               0x69);
+
+                       tmpV16 = rtl_read_word(rtlpriv,
+                                              rtlpriv->cfg->maps[SYS_ISO_CTRL]);
+                       if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
+                               tmpV16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V];
+                               rtl_write_word(rtlpriv,
+                                              rtlpriv->cfg->maps[SYS_ISO_CTRL],
+                                              tmpV16);
+                       }
+
+                       tmpV16 = rtl_read_word(rtlpriv,
+                                              rtlpriv->cfg->maps[SYS_FUNC_EN]);
+                       if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) {
+                               tmpV16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR];
+                               rtl_write_word(rtlpriv,
+                                              rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16);
+                       }
+
+                       tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]);
+                       if ((!(tmpV16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) ||
+                           (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) {
+                               tmpV16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] |
+                                          rtlpriv->cfg->maps[EFUSE_ANA8M]);
+                               rtl_write_word(rtlpriv,
+                                              rtlpriv->cfg->maps[SYS_CLK], tmpV16);
+                       }
+               }
+
+               if (pwrstate == true) {
+                       if (bwrite == true) {
+                               tempval = rtl_read_byte(rtlpriv,
+                                                       rtlpriv->cfg->maps[EFUSE_TEST] +
+                                                       3);
+
+                               if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
+                                       tempval &= 0x0F;
+                                       tempval |= (VOLTAGE_V25 << 4);
+                               }
+
+                               rtl_write_byte(rtlpriv,
+                                              rtlpriv->cfg->maps[EFUSE_TEST] + 3,
+                                              (tempval | 0x80));
+                       }
+
+                       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+                               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+                                                       0x03);
+                       }
+
+               } else {
+                       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE)
+                               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0);
+
+                       if (bwrite == true) {
+                               tempval = rtl_read_byte(rtlpriv,
+                                                       rtlpriv->cfg->maps[EFUSE_TEST] +
+                                                       3);
+                               rtl_write_byte(rtlpriv,
+                                              rtlpriv->cfg->maps[EFUSE_TEST] + 3,
+                                              (tempval & 0x7F));
+                       }
+
+                       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+                               rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+                                                       0x02);
+                       }
+
+               }
+       }
+
+}
+
+static u16 efuse_get_current_size(struct ieee80211_hw *hw)
+{
+       int bcontinual = true;
+       u16 efuse_addr = 0;
+       u8 hoffset, hworden;
+       u8 efuse_data, word_cnts;
+
+       while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
+              && (efuse_addr < EFUSE_MAX_SIZE)) {
+               if (efuse_data != 0xFF) {
+                       hoffset = (efuse_data >> 4) & 0x0F;
+                       hworden = efuse_data & 0x0F;
+                       word_cnts = efuse_calculate_word_cnts(hworden);
+                       efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+               } else {
+                       bcontinual = false;
+               }
+       }
+
+       return efuse_addr;
+}
+
+static u8 efuse_calculate_word_cnts(u8 word_en)
+{
+       u8 word_cnts = 0;
+       if (!(word_en & BIT(0)))
+               word_cnts++;
+       if (!(word_en & BIT(1)))
+               word_cnts++;
+       if (!(word_en & BIT(2)))
+               word_cnts++;
+       if (!(word_en & BIT(3)))
+               word_cnts++;
+       return word_cnts;
+}
+
diff --git a/drivers/staging/rtl8821ae/efuse.h b/drivers/staging/rtl8821ae/efuse.h
new file mode 100644 (file)
index 0000000..a9fcbe0
--- /dev/null
@@ -0,0 +1,130 @@
+/******************************************************************************
+ *
+ * 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_EFUSE_H_
+#define __RTL_EFUSE_H_
+
+#define EFUSE_IC_ID_OFFSET             506
+
+/*
+#define EFUSE_REAL_CONTENT_LEN 512
+#define EFUSE_MAP_LEN                  128
+#define EFUSE_MAX_SECTION              16
+#define EFUSE_MAX_WORD_UNIT            4
+#define EFUSE_IC_ID_OFFSET             506
+*/
+
+#define EFUSE_MAX_WORD_UNIT            4
+
+#define EFUSE_INIT_MAP                 0
+#define EFUSE_MODIFY_MAP               1
+
+#define PG_STATE_HEADER                0x01
+#define PG_STATE_WORD_0                        0x02
+#define PG_STATE_WORD_1                        0x04
+#define PG_STATE_WORD_2                        0x08
+#define PG_STATE_WORD_3                        0x10
+#define PG_STATE_DATA                  0x20
+
+#define PG_SWBYTE_H                    0x01
+#define PG_SWBYTE_L                    0x02
+
+#define _POWERON_DELAY_
+#define _PRE_EXECUTE_READ_CMD_
+
+#define EFUSE_REPEAT_THRESHOLD_                3
+#define EFUSE_ERROE_HANDLE             1
+
+struct efuse_map {
+       u8 offset;
+       u8 word_start;
+       u8 byte_start;
+       u8 byte_cnts;
+};
+
+struct pgpkt_struct {
+       u8 offset;
+       u8 word_en;
+       u8 data[8];
+};
+
+enum efuse_data_item {
+       EFUSE_CHIP_ID = 0,
+       EFUSE_LDO_SETTING,
+       EFUSE_CLK_SETTING,
+       EFUSE_SDIO_SETTING,
+       EFUSE_CCCR,
+       EFUSE_SDIO_MODE,
+       EFUSE_OCR,
+       EFUSE_F0CIS,
+       EFUSE_F1CIS,
+       EFUSE_MAC_ADDR,
+       EFUSE_EEPROM_VER,
+       EFUSE_CHAN_PLAN,
+       EFUSE_TXPW_TAB
+};
+
+enum {
+       VOLTAGE_V25 = 0x03,
+       LDOE25_SHIFT = 28,
+};
+
+struct efuse_priv {
+       u8 id[2];
+       u8 ldo_setting[2];
+       u8 clk_setting[2];
+       u8 cccr;
+       u8 sdio_mode;
+       u8 ocr[3];
+       u8 cis0[17];
+       u8 cis1[48];
+       u8 mac_addr[6];
+       u8 eeprom_verno;
+       u8 channel_plan;
+       u8 tx_power_b[14];
+       u8 tx_power_g[14];
+};
+
+extern void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
+extern void efuse_initialize(struct ieee80211_hw *hw);
+extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
+extern int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data);
+extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
+extern void read_efuse(struct ieee80211_hw *hw, u16 _offset,
+                      u16 _size_byte, u8 * pbuf);
+extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
+                             u16 offset, u32 * value);
+extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type,
+                              u16 offset, u32 value);
+extern bool efuse_shadow_update(struct ieee80211_hw *hw);
+extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw);
+extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw);
+extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw);
+extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
+#endif
diff --git a/drivers/staging/rtl8821ae/pci.c b/drivers/staging/rtl8821ae/pci.c
new file mode 100644 (file)
index 0000000..cfa651e
--- /dev/null
@@ -0,0 +1,2549 @@
+/******************************************************************************
+ *
+ * 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 "core.h"
+#include "wifi.h"
+#include "pci.h"
+#include "base.h"
+#include "ps.h"
+#include "efuse.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+#include <linux/export.h>
+#endif
+
+static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
+       INTEL_VENDOR_ID,
+       ATI_VENDOR_ID,
+       AMD_VENDOR_ID,
+       SIS_VENDOR_ID
+};
+
+static const u8 ac_to_hwq[] = {
+       VO_QUEUE,
+       VI_QUEUE,
+       BE_QUEUE,
+       BK_QUEUE
+};
+
+u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw,
+               struct sk_buff *skb)
+{
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u16 fc = rtl_get_fc(skb);
+       u8 queue_index = skb_get_queue_mapping(skb);
+
+       if (unlikely(ieee80211_is_beacon(fc)))
+               return BEACON_QUEUE;
+       if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
+               return MGNT_QUEUE;
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+               if (ieee80211_is_nullfunc(fc))
+                       return HIGH_QUEUE;
+
+       return ac_to_hwq[queue_index];
+}
+
+/* Update PCI dependent default settings*/
+static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+       u8 init_aspm;
+
+       ppsc->reg_rfps_level = 0;
+       ppsc->b_support_aspm = 0;
+
+       /*Update PCI ASPM setting */
+       ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm;
+       switch (rtlpci->const_pci_aspm) {
+       case 0:
+               /*No ASPM */
+               break;
+
+       case 1:
+               /*ASPM dynamically enabled/disable. */
+               ppsc->reg_rfps_level |= RT_RF_LPS_LEVEL_ASPM;
+               break;
+
+       case 2:
+               /*ASPM with Clock Req dynamically enabled/disable. */
+               ppsc->reg_rfps_level |= (RT_RF_LPS_LEVEL_ASPM |
+                                        RT_RF_OFF_LEVL_CLK_REQ);
+               break;
+
+       case 3:
+               /*
+                * Always enable ASPM and Clock Req
+                * from initialization to halt.
+                * */
+               ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM);
+               ppsc->reg_rfps_level |= (RT_RF_PS_LEVEL_ALWAYS_ASPM |
+                                        RT_RF_OFF_LEVL_CLK_REQ);
+               break;
+
+       case 4:
+               /*
+                * Always enable ASPM without Clock Req
+                * from initialization to halt.
+                * */
+               ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM |
+                                         RT_RF_OFF_LEVL_CLK_REQ);
+               ppsc->reg_rfps_level |= RT_RF_PS_LEVEL_ALWAYS_ASPM;
+               break;
+       }
+
+       ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC;
+
+       /*Update Radio OFF setting */
+       switch (rtlpci->const_hwsw_rfoff_d3) {
+       case 1:
+               if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM)
+                       ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM;
+               break;
+
+       case 2:
+               if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM)
+                       ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM;
+               ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC;
+               break;
+
+       case 3:
+               ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_PCI_D3;
+               break;
+       }
+
+       /*Set HW definition to determine if it supports ASPM. */
+       switch (rtlpci->const_support_pciaspm) {
+       case 0:{
+                       /*Not support ASPM. */
+                       bool b_support_aspm = false;
+                       ppsc->b_support_aspm = b_support_aspm;
+                       break;
+               }
+       case 1:{
+                       /*Support ASPM. */
+                       bool b_support_aspm = true;
+                       bool b_support_backdoor = true;
+                       ppsc->b_support_aspm = b_support_aspm;
+
+                       /*if(priv->oem_id == RT_CID_TOSHIBA &&
+                          !priv->ndis_adapter.amd_l1_patch)
+                          b_support_backdoor = false; */
+
+                       ppsc->b_support_backdoor = b_support_backdoor;
+
+                       break;
+               }
+       case 2:
+               /*ASPM value set by chipset. */
+               if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) {
+                       bool b_support_aspm = true;
+                       ppsc->b_support_aspm = b_support_aspm;
+               }
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       }
+
+       /* toshiba aspm issue, toshiba will set aspm selfly
+        * so we should not set aspm in driver */
+       pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm);
+       if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE &&
+               init_aspm == 0x43)
+               ppsc->b_support_aspm = false;
+}
+
+static bool _rtl_pci_platform_switch_device_pci_aspm(struct ieee80211_hw *hw,
+                                                    u8 value)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool bresult = false;
+
+       if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)
+               value |= 0x40;
+
+       pci_write_config_byte(rtlpci->pdev, 0x80, value);
+
+       return bresult;
+}
+
+/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
+static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool bresult = false;
+
+       pci_write_config_byte(rtlpci->pdev, 0x81, value);
+       bresult = true;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+               udelay(100);
+
+       return bresult;
+}
+
+/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
+static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+       u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+       u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
+       /*Retrieve original configuration settings. */
+       u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg;
+       u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
+                               pcibridge_linkctrlreg;
+       u16 aspmlevel = 0;
+
+       if (!ppsc->b_support_aspm)
+               return;
+
+       if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
+               RT_TRACE(COMP_POWER, DBG_TRACE,
+                        ("PCI(Bridge) UNKNOWN.\n"));
+
+               return;
+       }
+
+       if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
+               RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
+               _rtl_pci_switch_clk_req(hw, 0x0);
+       }
+
+       if (1) {
+               /*for promising device will in L0 state after an I/O. */
+               u8 tmp_u1b;
+               pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
+       }
+
+       /*Set corresponding value. */
+       aspmlevel |= BIT(0) | BIT(1);
+       linkctrl_reg &= ~aspmlevel;
+       pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1));
+
+       _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg);
+       udelay(50);
+
+       /*4 Disable Pci Bridge ASPM */
+       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+                                    pcicfg_addrport + (num4bytes << 2));
+       rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg);
+
+       udelay(50);
+
+}
+
+/*
+ *Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for
+ *power saving We should follow the sequence to enable
+ *RTL8192SE first then enable Pci Bridge ASPM
+ *or the system will show bluescreen.
+ */
+static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+       u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+       u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
+       u16 aspmlevel;
+       u8 u_pcibridge_aspmsetting;
+       u8 u_device_aspmsetting;
+
+       if (!ppsc->b_support_aspm)
+               return;
+
+       if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
+               RT_TRACE(COMP_POWER, DBG_TRACE,
+                        ("PCI(Bridge) UNKNOWN.\n"));
+               return;
+       }
+
+       /*4 Enable Pci Bridge ASPM */
+       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+                                    pcicfg_addrport + (num4bytes << 2));
+
+       u_pcibridge_aspmsetting =
+           pcipriv->ndis_adapter.pcibridge_linkctrlreg |
+           rtlpci->const_hostpci_aspm_setting;
+
+       if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
+               u_pcibridge_aspmsetting &= ~BIT(0);
+
+       rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, u_pcibridge_aspmsetting);
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("PlatformEnableASPM(): Write reg[%x] = %x\n",
+                 (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
+                 u_pcibridge_aspmsetting));
+
+       udelay(50);
+
+       /*Get ASPM level (with/without Clock Req) */
+       aspmlevel = rtlpci->const_devicepci_aspm_setting;
+       u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg;
+
+       /*_rtl_pci_platform_switch_device_pci_aspm(dev,*/
+       /*(priv->ndis_adapter.linkctrl_reg | ASPMLevel)); */
+
+       u_device_aspmsetting |= aspmlevel;
+
+       _rtl_pci_platform_switch_device_pci_aspm(hw, u_device_aspmsetting);
+
+       if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
+               _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level &
+                                            RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
+               RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
+       }
+       udelay(100);
+}
+
+static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+
+       bool status = false;
+       u8 offset_e0;
+       unsigned offset_e4;
+
+       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+                       pcicfg_addrport + 0xE0);
+       rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, 0xA0);
+
+       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+                       pcicfg_addrport + 0xE0);
+       rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &offset_e0);
+
+       if (offset_e0 == 0xA0) {
+               rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+                                            pcicfg_addrport + 0xE4);
+               rtl_pci_raw_read_port_ulong(PCI_CONF_DATA, &offset_e4);
+               if (offset_e4 & BIT(23))
+                       status = true;
+       }
+
+       return status;
+}
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+static u8 _rtl_pci_get_pciehdr_offset(struct ieee80211_hw *hw)
+{
+       u8 capability_offset;
+       u8 num4bytes = 0x34/4;
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       u32 pcicfg_addr_port = (pcipriv->ndis_adapter.pcibridge_busnum << 16)|
+                              (pcipriv->ndis_adapter.pcibridge_devnum << 11)|
+                              (pcipriv->ndis_adapter.pcibridge_funcnum << 8)|
+                              (1 << 31);
+
+       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS , pcicfg_addr_port
+                                                       + (num4bytes << 2));
+       rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &capability_offset);
+       while (capability_offset != 0) {
+               struct rtl_pci_capabilities_header capability_hdr;
+
+               num4bytes = capability_offset / 4;
+               /* Read the header of the capability at  this offset.
+                * If the retrieved capability is not the power management
+                * capability that we are looking for, follow the link to
+                * the next capability and continue looping.
+                */
+               rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS , 
+                                            pcicfg_addr_port + 
+                                            (num4bytes << 2));
+               rtl_pci_raw_read_port_ushort(PCI_CONF_DATA,
+                                            (u16*)&capability_hdr);
+               /* Found the PCI express capability. */
+               if (capability_hdr.capability_id == 
+                   PCI_CAPABILITY_ID_PCI_EXPRESS)
+                       break;
+               else
+                       capability_offset = capability_hdr.next;
+       }
+       return capability_offset;
+}
+#endif
+/*<delete in kernel end>*/
+
+bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw,
+                             struct rtl_priv **buddy_priv)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       bool b_find_buddy_priv = false;
+       struct rtl_priv *temp_priv = NULL;
+       struct rtl_pci_priv *temp_pcipriv = NULL;
+
+       if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) {
+               list_for_each_entry(temp_priv, &rtlpriv->glb_var->glb_priv_list,
+                       list) {
+                       if (temp_priv) {
+                               temp_pcipriv = 
+                                       (struct rtl_pci_priv *)temp_priv->priv;
+                               RT_TRACE(COMP_INIT, DBG_LOUD,
+                                       (("pcipriv->ndis_adapter.funcnumber %x \n"),
+                                       pcipriv->ndis_adapter.funcnumber));
+                               RT_TRACE(COMP_INIT, DBG_LOUD,
+                                       (("temp_pcipriv->ndis_adapter.funcnumber %x \n"),
+                                       temp_pcipriv->ndis_adapter.funcnumber));
+
+                               if ((pcipriv->ndis_adapter.busnumber ==
+                                       temp_pcipriv->ndis_adapter.busnumber) &&
+                                   (pcipriv->ndis_adapter.devnumber ==
+                                   temp_pcipriv->ndis_adapter.devnumber) &&
+                                   (pcipriv->ndis_adapter.funcnumber !=
+                                   temp_pcipriv->ndis_adapter.funcnumber)) {
+                                       b_find_buddy_priv = true;
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+               (("b_find_buddy_priv %d \n"), b_find_buddy_priv));
+
+       if (b_find_buddy_priv)
+               *buddy_priv = temp_priv;
+
+       return b_find_buddy_priv;
+}
+
+void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
+       u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+       u8 linkctrl_reg;
+       u8 num4bbytes;
+
+       num4bbytes = (capabilityoffset + 0x10) / 4;
+
+       /*Read  Link Control Register */
+       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
+                                    pcicfg_addrport + (num4bbytes << 2));
+       rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);
+
+       pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
+}
+
+static void rtl_pci_parse_configuration(struct pci_dev *pdev,
+                                       struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+
+       u8 tmp;
+       int pos;
+       u8 linkctrl_reg;
+
+       /*Link Control Register */
+       pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+       pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg);
+       pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg;
+
+       RT_TRACE(COMP_INIT, DBG_TRACE,
+                ("Link Control Register =%x\n",
+                 pcipriv->ndis_adapter.linkctrl_reg));
+
+       pci_read_config_byte(pdev, 0x98, &tmp);
+       tmp |= BIT(4);
+       pci_write_config_byte(pdev, 0x98, tmp);
+
+       tmp = 0x17;
+       pci_write_config_byte(pdev, 0x70f, tmp);
+}
+
+static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
+{
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       _rtl_pci_update_default_setting(hw);
+
+       if (ppsc->reg_rfps_level & RT_RF_PS_LEVEL_ALWAYS_ASPM) {
+               /*Always enable ASPM & Clock Req. */
+               rtl_pci_enable_aspm(hw);
+               RT_SET_PS_LEVEL(ppsc, RT_RF_PS_LEVEL_ALWAYS_ASPM);
+       }
+
+}
+
+static void _rtl_pci_io_handler_init(struct device *dev,
+                                    struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->io.dev = dev;
+
+       rtlpriv->io.write8_async = pci_write8_async;
+       rtlpriv->io.write16_async = pci_write16_async;
+       rtlpriv->io.write32_async = pci_write32_async;
+
+       rtlpriv->io.read8_sync = pci_read8_sync;
+       rtlpriv->io.read16_sync = pci_read16_sync;
+       rtlpriv->io.read32_sync = pci_read32_sync;
+
+}
+
+static bool _rtl_pci_update_earlymode_info(struct ieee80211_hw *hw,
+                                          struct sk_buff *skb, 
+                                          struct rtl_tcb_desc *tcb_desc, 
+                                          u8 tid)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 additionlen = FCS_LEN;
+       struct sk_buff *next_skb;
+               
+       /* here open is 4, wep/tkip is 8, aes is 12*/
+       if (info->control.hw_key)
+               additionlen += info->control.hw_key->icv_len;
+
+       /* The most skb num is 6 */
+       tcb_desc->empkt_num = 0;
+       spin_lock_bh(&rtlpriv->locks.waitq_lock);
+       skb_queue_walk(&rtlpriv->mac80211.skb_waitq[tid], next_skb) {
+               struct ieee80211_tx_info *next_info = 
+                                       IEEE80211_SKB_CB(next_skb);
+               if (next_info->flags & IEEE80211_TX_CTL_AMPDU) {
+                       tcb_desc->empkt_len[tcb_desc->empkt_num] =
+                               next_skb->len + additionlen;
+                       tcb_desc->empkt_num++;
+               } else {
+                       break;
+               }
+
+               if (skb_queue_is_last(&rtlpriv->mac80211.skb_waitq[tid], 
+                                     next_skb))
+                       break;
+
+               if (tcb_desc->empkt_num >= rtlhal->max_earlymode_num)
+                       break;
+       }
+       spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+       return true;
+}
+
+/* just for early mode now */
+static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct sk_buff *skb = NULL;
+       struct ieee80211_tx_info *info = NULL;
+       int tid; /* should be int */
+       
+       if (!rtlpriv->rtlhal.b_earlymode_enable)
+               return; 
+       if (rtlpriv->dm.supp_phymode_switch &&
+               (rtlpriv->easy_concurrent_ctl.bswitch_in_process ||
+               (rtlpriv->buddy_priv && 
+                rtlpriv->buddy_priv->easy_concurrent_ctl.bswitch_in_process)))
+               return;
+       /* we juse use em for BE/BK/VI/VO */
+       for (tid = 7; tid >= 0; tid--) {
+               u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(hw, tid)];
+               struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+               while (!mac->act_scanning && 
+                      rtlpriv->psc.rfpwr_state == ERFON) {
+                       struct rtl_tcb_desc tcb_desc;
+                       memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));                      
+
+                       spin_lock_bh(&rtlpriv->locks.waitq_lock);
+                       if (!skb_queue_empty(&mac->skb_waitq[tid]) &&
+                           (ring->entries - skb_queue_len(&ring->queue) > 
+                            rtlhal->max_earlymode_num)) {
+                               skb = skb_dequeue(&mac->skb_waitq[tid]);
+                       } else {
+                               spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+                               break;
+                       }
+                       spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+                       /* Some macaddr can't do early mode. like
+                        * multicast/broadcast/no_qos data */
+                       info = IEEE80211_SKB_CB(skb);
+                       if (info->flags & IEEE80211_TX_CTL_AMPDU)
+                               _rtl_pci_update_earlymode_info(hw, skb, 
+                                                              &tcb_desc, tid);
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+                       rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+#else
+/*<delete in kernel end>*/
+                       rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, &tcb_desc);
+#endif
+/*<delete in kernel end>*/
+               }
+       }
+}
+
+static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
+
+       while (skb_queue_len(&ring->queue)) {
+               struct sk_buff *skb;
+               struct ieee80211_tx_info *info;
+               u16 fc;
+               u8 tid;
+               u8 *entry;
+
+               
+               if (rtlpriv->use_new_trx_flow)
+                       entry = (u8 *)(&ring->buffer_desc[ring->idx]);
+               else
+                       entry = (u8 *)(&ring->desc[ring->idx]);
+
+               if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx))
+                       return;
+                       
+               ring->idx = (ring->idx + 1) % ring->entries;
+               
+               skb = __skb_dequeue(&ring->queue);
+               
+               pci_unmap_single(rtlpci->pdev,
+                                le32_to_cpu(rtlpriv->cfg->ops->
+                                            get_desc((u8 *) entry, true,
+                                                     HW_DESC_TXBUFF_ADDR)),
+                                skb->len, PCI_DMA_TODEVICE);
+
+               /* remove early mode header */
+               if(rtlpriv->rtlhal.b_earlymode_enable)
+                       skb_pull(skb, EM_HDR_LEN);
+
+               RT_TRACE((COMP_INTR | COMP_SEND), DBG_TRACE,
+                        ("new ring->idx:%d, "
+                         "free: skb_queue_len:%d, free: seq:%d\n",
+                         ring->idx,
+                         skb_queue_len(&ring->queue),
+                         *(u16 *) (skb->data + 22)));
+
+               if(prio == TXCMD_QUEUE) {
+                       dev_kfree_skb(skb);
+                       goto tx_status_ok;
+
+               }
+
+               /* for sw LPS, just after NULL skb send out, we can
+                * sure AP kown we are sleeped, our we should not let
+                * rf to sleep*/
+               fc = rtl_get_fc(skb);
+               if (ieee80211_is_nullfunc(fc)) {
+                       if(ieee80211_has_pm(fc)) {
+                               rtlpriv->mac80211.offchan_deley = true;
+                               rtlpriv->psc.state_inap = 1;
+                       } else {
+                               rtlpriv->psc.state_inap = 0;
+                       }
+               }
+               if (ieee80211_is_action(fc)) {
+                       struct ieee80211_mgmt_compat *action_frame =
+                               (struct ieee80211_mgmt_compat *)skb->data;
+                       if (action_frame->u.action.u.ht_smps.action ==
+                               WLAN_HT_ACTION_SMPS) {
+                               dev_kfree_skb(skb);
+                               goto tx_status_ok;
+                       }
+               }
+
+               /* update tid tx pkt num */
+               tid = rtl_get_tid(skb);
+               if (tid <= 7)
+                       rtlpriv->link_info.tidtx_inperiod[tid]++;
+
+               info = IEEE80211_SKB_CB(skb);
+               ieee80211_tx_info_clear_status(info);
+
+               info->flags |= IEEE80211_TX_STAT_ACK;
+               /*info->status.rates[0].count = 1; */
+
+               ieee80211_tx_status_irqsafe(hw, skb);
+
+               if ((ring->entries - skb_queue_len(&ring->queue))
+                               == 2) {
+
+                       RT_TRACE(COMP_ERR, DBG_LOUD,
+                                       ("more desc left, wake"
+                                        "skb_queue@%d,ring->idx = %d,"
+                                        "skb_queue_len = 0x%d\n",
+                                        prio, ring->idx,
+                                        skb_queue_len(&ring->queue)));
+
+                       ieee80211_wake_queue(hw,
+                                       skb_get_queue_mapping
+                                       (skb));
+               }
+tx_status_ok:
+               skb = NULL;
+       }
+
+       if (((rtlpriv->link_info.num_rx_inperiod +
+               rtlpriv->link_info.num_tx_inperiod) > 8) ||
+               (rtlpriv->link_info.num_rx_inperiod > 2)) {
+               rtl_lps_leave(hw);
+       }
+}
+
+static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
+       u8 *entry, int rxring_idx, int desc_idx)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u32 bufferaddress;
+       u8 tmp_one = 1;
+       struct sk_buff *skb;
+
+       skb = dev_alloc_skb(rtlpci->rxbuffersize);      
+       if (!skb)
+               return 0;
+       rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
+
+       /* just set skb->cb to mapping addr
+        * for pci_unmap_single use */
+       *((dma_addr_t *) skb->cb) = pci_map_single(rtlpci->pdev,
+                               skb_tail_pointer(skb), rtlpci->rxbuffersize,
+                               PCI_DMA_FROMDEVICE);
+       bufferaddress = cpu_to_le32(*((dma_addr_t *) skb->cb));
+       if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
+               return 0;
+       if (rtlpriv->use_new_trx_flow) {
+               rtlpriv->cfg->ops->set_desc(hw, (u8 *) entry, false, 
+                                           HW_DESC_RX_PREPARE,
+                                           (u8 *) & bufferaddress);
+       } else {        
+               rtlpriv->cfg->ops->set_desc(hw, (u8 *) entry, false, 
+                                           HW_DESC_RXBUFF_ADDR,
+                                           (u8 *) & bufferaddress);
+               rtlpriv->cfg->ops->set_desc(hw, (u8 *) entry, false, 
+                                           HW_DESC_RXPKT_LEN,
+                                           (u8 *) & rtlpci->rxbuffersize);
+               rtlpriv->cfg->ops->set_desc(hw, (u8 *) entry, false, 
+                                           HW_DESC_RXOWN,
+                                           (u8 *) & tmp_one);
+       }
+       
+       return 1;
+}
+
+/* inorder to receive 8K AMSDU we have set skb to
+ * 9100bytes in init rx ring, but if this packet is
+ * not a AMSDU, this so big packet will be sent to
+ * TCP/IP directly, this cause big packet ping fail
+ * like: "ping -s 65507", so here we will realloc skb
+ * based on the true size of packet, I think mac80211
+ * do it will be better, but now mac80211 haven't */
+
+/* but some platform will fail when alloc skb sometimes.
+ * in this condition, we will send the old skb to
+ * mac80211 directly, this will not cause any other
+ * issues, but only be losted by TCP/IP */
+static void _rtl_pci_rx_to_mac80211(struct ieee80211_hw *hw,
+       struct sk_buff *skb, struct ieee80211_rx_status rx_status)
+{
+       if (unlikely(!rtl_action_proc(hw, skb, false))) {
+               dev_kfree_skb_any(skb);
+       } else {
+               struct sk_buff *uskb = NULL;
+               u8 *pdata;
+               
+               uskb = dev_alloc_skb(skb->len + 128);
+               if (likely(uskb)) {
+                       memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
+                                       sizeof(rx_status));
+                       pdata = (u8 *)skb_put(uskb, skb->len);
+                       memcpy(pdata, skb->data, skb->len);
+                       dev_kfree_skb_any(skb);
+
+                       ieee80211_rx_irqsafe(hw, uskb);
+               } else {
+                       ieee80211_rx_irqsafe(hw, skb);
+               }       
+       }
+}
+
+/*hsisr interrupt handler*/
+static void _rtl_pci_hs_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[MAC_HSISR], 
+                      rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[MAC_HSISR]) | 
+                      rtlpci->sys_irq_mask);
+
+       
+}
+static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       int rxring_idx = RTL_PCI_RX_MPDU_QUEUE;
+
+       struct ieee80211_rx_status rx_status = { 0 };
+       unsigned int count = rtlpci->rxringcount;
+       bool unicast = false;
+       u8 hw_queue = 0;
+       unsigned int rx_remained_cnt;
+       u8 own;
+       u8 tmp_one;
+
+       struct rtl_stats status = {
+               .signal = 0,
+               .noise = -98,
+               .rate = 0,
+       };
+       
+       /*RX NORMAL PKT */
+       while (count--) {
+               struct ieee80211_hdr *hdr;
+               u16 fc;
+               u16 len;
+               /*rx buffer descriptor */
+               struct rtl_rx_buffer_desc *buffer_desc = NULL;
+               /*if use new trx flow, it means wifi info */
+               struct rtl_rx_desc *pdesc = NULL;
+               /*rx pkt */
+               struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[
+                                       rtlpci->rx_ring[rxring_idx].idx];
+               
+               if (rtlpriv->use_new_trx_flow) {
+                       rx_remained_cnt = 
+                               rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw,
+                                                                     hw_queue);
+                       if (rx_remained_cnt < 1) 
+                               return;
+                       
+               } else {        /* rx descriptor */
+                       pdesc = &rtlpci->rx_ring[rxring_idx].desc[
+                               rtlpci->rx_ring[rxring_idx].idx];
+                       
+                       own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
+                                                              false, 
+                                                              HW_DESC_OWN);
+                       if (own) /* wait data to be filled by hardware */
+                               return;
+               }
+               
+               /* Get here means: data is filled already*/
+               /* AAAAAAttention !!!
+                * We can NOT access 'skb' before 'pci_unmap_single' */
+               pci_unmap_single(rtlpci->pdev, *((dma_addr_t *) skb->cb),
+                                rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
+               
+               if (rtlpriv->use_new_trx_flow) {
+                       buffer_desc = &rtlpci->rx_ring[rxring_idx].buffer_desc[
+                               rtlpci->rx_ring[rxring_idx].idx];
+                       /*means rx wifi info*/
+                       pdesc = (struct rtl_rx_desc *)skb->data;
+               }
+               
+               rtlpriv->cfg->ops->query_rx_desc(hw, &status,
+                                                &rx_status, (u8 *) pdesc, skb);
+                       
+               if (rtlpriv->use_new_trx_flow)
+                       rtlpriv->cfg->ops->rx_check_dma_ok(hw, 
+                                                          (u8 *)buffer_desc, 
+                                                          hw_queue);
+
+                       
+               len = rtlpriv->cfg->ops->get_desc((u8 *)pdesc, false, 
+                                                 HW_DESC_RXPKT_LEN);
+                       
+               if (skb->end - skb->tail > len) {
+                       skb_put(skb, len);
+                       if (rtlpriv->use_new_trx_flow)  
+                               skb_reserve(skb, status.rx_drvinfo_size + 
+                                                status.rx_bufshift + 24);
+                       else
+                               skb_reserve(skb, status.rx_drvinfo_size + 
+                                                status.rx_bufshift);
+
+               } else {
+                       printk("skb->end - skb->tail = %d, len is %d\n", 
+                              skb->end - skb->tail, len);
+                       break;
+               }
+                       
+               rtlpriv->cfg->ops->rx_command_packet_handler(hw, status, skb);
+
+               /*
+                *NOTICE This can not be use for mac80211,
+                *this is done in mac80211 code,
+                *if you done here sec DHCP will fail
+                *skb_trim(skb, skb->len - 4);
+                */
+
+               hdr = rtl_get_hdr(skb);
+               fc = rtl_get_fc(skb);
+               
+               if (!status.b_crc && !status.b_hwerror) {
+                       memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, 
+                              sizeof(rx_status));
+
+                       if (is_broadcast_ether_addr(hdr->addr1)) {
+                               ;/*TODO*/
+                       } else if (is_multicast_ether_addr(hdr->addr1)) {
+                               ;/*TODO*/
+                       } else {
+                               unicast = true;
+                               rtlpriv->stats.rxbytesunicast += skb->len;
+                       }
+
+                       rtl_is_special_data(hw, skb, false);
+
+                       if (ieee80211_is_data(fc)) {
+                               rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
+
+                               if (unicast)
+                                       rtlpriv->link_info.num_rx_inperiod++;
+                       }
+
+                       /* static bcn for roaming */
+                       rtl_beacon_statistic(hw, skb);
+                       rtl_p2p_info(hw, (void*)skb->data, skb->len);   
+                       /* for sw lps */
+                       rtl_swlps_beacon(hw, (void*)skb->data, skb->len);
+                       rtl_recognize_peer(hw, (void*)skb->data, skb->len);
+                       if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) &&
+                           (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)&&
+                           (ieee80211_is_beacon(fc) || 
+                            ieee80211_is_probe_resp(fc))) {
+                               dev_kfree_skb_any(skb);
+                       } else {
+                               _rtl_pci_rx_to_mac80211(hw, skb, rx_status);
+                       }
+               } else {
+                       dev_kfree_skb_any(skb);
+               }
+               if (rtlpriv->use_new_trx_flow) {
+                       rtlpci->rx_ring[hw_queue].next_rx_rp += 1;
+                       rtlpci->rx_ring[hw_queue].next_rx_rp %= 
+                                                       RTL_PCI_MAX_RX_COUNT;
+
+
+                       rx_remained_cnt--;
+                       if (1/*rx_remained_cnt == 0*/) {
+                               rtl_write_word(rtlpriv, 0x3B4, 
+                                       rtlpci->rx_ring[hw_queue].next_rx_rp);
+                       }
+               }
+               if (((rtlpriv->link_info.num_rx_inperiod +
+                     rtlpriv->link_info.num_tx_inperiod) > 8) ||
+                   (rtlpriv->link_info.num_rx_inperiod > 2)) {
+                       rtl_lps_leave(hw);
+               }
+
+               if (rtlpriv->use_new_trx_flow) {
+                       _rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc, 
+                                                rxring_idx,
+                                              rtlpci->rx_ring[rxring_idx].idx);                        
+               } else {
+                       _rtl_pci_init_one_rxdesc(hw, (u8 *)pdesc, rxring_idx,
+                                              rtlpci->rx_ring[rxring_idx].idx);                        
+
+                       if (rtlpci->rx_ring[rxring_idx].idx == 
+                           rtlpci->rxringcount - 1)
+                               rtlpriv->cfg->ops->set_desc(hw, (u8 *) pdesc, 
+                                                           false, 
+                                                           HW_DESC_RXERO,
+                                                           (u8 *) & tmp_one);
+               }
+               rtlpci->rx_ring[rxring_idx].idx = 
+                               (rtlpci->rx_ring[rxring_idx].idx + 1) % 
+                               rtlpci->rxringcount;
+       }
+}
+
+static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
+{
+       struct ieee80211_hw *hw = dev_id;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       unsigned long flags;
+       u32 inta = 0;
+       u32 intb = 0;
+
+       
+
+       if (rtlpci->irq_enabled == 0)
+               return IRQ_HANDLED;
+
+       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock,flags);
+
+
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[MAC_HIMR], 0x0);
+       
+
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[MAC_HIMRE], 0x0);
+
+
+       /*read ISR: 4/8bytes */
+       rtlpriv->cfg->ops->interrupt_recognized(hw, &inta, &intb);
+
+
+       /*Shared IRQ or HW disappared */
+       if (!inta || inta == 0xffff)
+               goto done;
+       /*<1> beacon related */
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) {
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("beacon ok interrupt!\n"));
+       }
+
+       if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) {
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("beacon err interrupt!\n"));
+       }
+
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) {
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("beacon interrupt!\n"));
+       }
+
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) {
+               RT_TRACE(COMP_INTR, DBG_TRACE,
+                        ("prepare beacon for interrupt!\n"));
+               tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet);
+       }
+
+
+       /*<2> tx related */
+       if (unlikely(intb & rtlpriv->cfg->maps[RTL_IMR_TXFOVW]))
+               RT_TRACE(COMP_ERR, DBG_TRACE, ("IMR_TXFOVW!\n"));
+
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) {
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("Manage ok interrupt!\n"));
+               _rtl_pci_tx_isr(hw, MGNT_QUEUE);
+       }
+
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) {
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("HIGH_QUEUE ok interrupt!\n"));
+               _rtl_pci_tx_isr(hw, HIGH_QUEUE);
+       }
+
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) {
+               rtlpriv->link_info.num_tx_inperiod++;
+
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("BK Tx OK interrupt!\n"));
+               _rtl_pci_tx_isr(hw, BK_QUEUE);
+       }
+
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) {
+               rtlpriv->link_info.num_tx_inperiod++;
+
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("BE TX OK interrupt!\n"));
+               _rtl_pci_tx_isr(hw, BE_QUEUE);
+       }
+
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) {
+               rtlpriv->link_info.num_tx_inperiod++;
+
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("VI TX OK interrupt!\n"));
+               _rtl_pci_tx_isr(hw, VI_QUEUE);
+       }
+
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) {
+               rtlpriv->link_info.num_tx_inperiod++;
+
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("Vo TX OK interrupt!\n"));
+               _rtl_pci_tx_isr(hw, VO_QUEUE);
+       }
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+               if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) {
+                       rtlpriv->link_info.num_tx_inperiod++;
+
+                       RT_TRACE(COMP_INTR, DBG_TRACE,
+                                ("CMD TX OK interrupt!\n"));
+                       _rtl_pci_tx_isr(hw, TXCMD_QUEUE);
+               }
+       }
+
+       /*<3> rx related */
+       if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
+               RT_TRACE(COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n"));
+
+               _rtl_pci_rx_interrupt(hw);
+
+       }
+
+       if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("rx descriptor unavailable!\n"));
+               rtl_write_byte(rtlpriv, 0xb4, BIT(1) );
+               _rtl_pci_rx_interrupt(hw);
+       }
+
+       if (unlikely(intb & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
+               RT_TRACE(COMP_ERR, DBG_WARNING, ("rx overflow !\n"));
+               _rtl_pci_rx_interrupt(hw);
+       }
+
+       /*<4> fw related*/
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) {
+               if (inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) {
+                       RT_TRACE(COMP_INTR, DBG_TRACE, 
+                                ("firmware interrupt!\n"));
+                       queue_delayed_work(rtlpriv->works.rtl_wq,
+                                          &rtlpriv->works.fwevt_wq, 0);
+               }
+       }
+
+       /*<5> hsisr related*/
+       /* Only 8188EE & 8723BE Supported.
+        * If Other ICs Come in, System will corrupt,
+        * because maps[RTL_IMR_HSISR_IND] & maps[MAC_HSISR]
+        * are not initialized*/
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE ||
+           rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) {
+               if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_HSISR_IND])) {
+                       RT_TRACE(COMP_INTR, DBG_TRACE, 
+                                        ("hsisr interrupt!\n"));
+                       _rtl_pci_hs_interrupt(hw);
+               }
+       }
+       
+
+       if(rtlpriv->rtlhal.b_earlymode_enable)
+               tasklet_schedule(&rtlpriv->works.irq_tasklet);
+
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[MAC_HIMR],
+                       rtlpci->irq_mask[0]);
+       rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[MAC_HIMRE],
+                       rtlpci->irq_mask[1]);
+       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+       
+       return IRQ_HANDLED;
+
+done:
+       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+       return IRQ_HANDLED;
+}
+
+static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
+{
+       _rtl_pci_tx_chk_waitq(hw);
+}
+
+static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl8192_tx_ring *ring = NULL;
+       struct ieee80211_hdr *hdr = NULL;
+       struct ieee80211_tx_info *info = NULL;
+       struct sk_buff *pskb = NULL;
+       struct rtl_tx_desc *pdesc = NULL;
+       struct rtl_tcb_desc tcb_desc;
+       /*This is for new trx flow*/
+       struct rtl_tx_buffer_desc *pbuffer_desc = NULL;
+       u8 temp_one = 1;
+
+       memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+       ring = &rtlpci->tx_ring[BEACON_QUEUE];
+       pskb = __skb_dequeue(&ring->queue);
+       if (pskb)
+               kfree_skb(pskb);
+
+       /*NB: the beacon data buffer must be 32-bit aligned. */
+       pskb = ieee80211_beacon_get(hw, mac->vif);
+       if (pskb == NULL)
+               return;
+       hdr = rtl_get_hdr(pskb);
+       info = IEEE80211_SKB_CB(pskb);
+       pdesc = &ring->desc[0];
+       if (rtlpriv->use_new_trx_flow)
+               pbuffer_desc = &ring->buffer_desc[0];
+       
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+       rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, 
+                                       (u8 *)pbuffer_desc, info, pskb, 
+                                       BEACON_QUEUE, &tcb_desc);
+#else
+/*<delete in kernel end>*/
+       rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
+                                       (u8 *)pbuffer_desc, info, NULL, pskb, 
+                                       BEACON_QUEUE, &tcb_desc);
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+
+       __skb_queue_tail(&ring->queue, pskb);
+
+       rtlpriv->cfg->ops->set_desc(hw, (u8 *) pdesc, true, HW_DESC_OWN,
+                                   (u8 *) & temp_one);
+
+       return;
+}
+
+static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u8 i;
+       u16 desc_num;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE)
+               desc_num = TX_DESC_NUM_92E;
+       else
+               desc_num = RT_TXDESC_NUM;
+       
+       for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
+               rtlpci->txringcount[i] = desc_num;
+       }
+       /*
+        *we just alloc 2 desc for beacon queue,
+        *because we just need first desc in hw beacon.
+        */
+       rtlpci->txringcount[BEACON_QUEUE] = 2;
+
+       /*
+        *BE queue need more descriptor for performance
+        *consideration or, No more tx desc will happen,
+        *and may cause mac80211 mem leakage.
+        */
+       if (rtl_priv(hw)->use_new_trx_flow == false)
+               rtlpci->txringcount[BE_QUEUE] = RT_TXDESC_NUM_BE_QUEUE;
+
+       rtlpci->rxbuffersize = 9100;    /*2048/1024; */
+       rtlpci->rxringcount = RTL_PCI_MAX_RX_COUNT;     /*64; */
+}
+
+static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
+               struct pci_dev *pdev)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       rtlpriv->rtlhal.up_first_time = true;
+       rtlpriv->rtlhal.being_init_adapter = false;
+
+       rtlhal->hw = hw;
+       rtlpci->pdev = pdev;
+
+       /*Tx/Rx related var */
+       _rtl_pci_init_trx_var(hw);
+
+       /*IBSS*/ mac->beacon_interval = 100;
+
+       /*AMPDU*/
+       mac->min_space_cfg = 0;
+       mac->max_mss_density = 0;
+       /*set sane AMPDU defaults */
+       mac->current_ampdu_density = 7;
+       mac->current_ampdu_factor = 3;
+
+       /*QOS*/
+       rtlpci->acm_method = eAcmWay2_SW;
+
+       /*task */
+       tasklet_init(&rtlpriv->works.irq_tasklet,
+                    (void (*)(unsigned long))_rtl_pci_irq_tasklet,
+                    (unsigned long)hw);
+       tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
+                    (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
+                    (unsigned long)hw);
+}
+
+static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
+                                unsigned int prio, unsigned int entries)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_tx_buffer_desc *buffer_desc;
+       struct rtl_tx_desc *desc;
+       dma_addr_t buffer_desc_dma, desc_dma;
+       u32 nextdescaddress;
+       int i;
+
+       /* alloc tx buffer desc for new trx flow*/
+       if (rtlpriv->use_new_trx_flow) {
+               buffer_desc = pci_alloc_consistent(rtlpci->pdev,
+                                           sizeof(*buffer_desc) * entries, 
+                                           &buffer_desc_dma);
+
+               if (!buffer_desc || (unsigned long)buffer_desc & 0xFF) {
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                                ("Cannot allocate TX ring (prio = %d)\n", 
+                                prio));
+                       return -ENOMEM;
+               }
+
+               memset(buffer_desc, 0, sizeof(*buffer_desc) * entries);
+               rtlpci->tx_ring[prio].buffer_desc = buffer_desc;
+               rtlpci->tx_ring[prio].buffer_desc_dma = buffer_desc_dma;
+               
+               rtlpci->tx_ring[prio].cur_tx_rp = 0;
+               rtlpci->tx_ring[prio].cur_tx_wp = 0;
+               rtlpci->tx_ring[prio].avl_desc = entries;
+
+       }
+       
+       /* alloc dma for this ring */
+       desc = pci_alloc_consistent(rtlpci->pdev,
+                                   sizeof(*desc) * entries, &desc_dma);
+
+       if (!desc || (unsigned long)desc & 0xFF) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Cannot allocate TX ring (prio = %d)\n", prio));
+               return -ENOMEM;
+       }
+
+       memset(desc, 0, sizeof(*desc) * entries);
+       rtlpci->tx_ring[prio].desc = desc;
+       rtlpci->tx_ring[prio].dma = desc_dma;
+       
+       rtlpci->tx_ring[prio].idx = 0;
+       rtlpci->tx_ring[prio].entries = entries;
+       skb_queue_head_init(&rtlpci->tx_ring[prio].queue);
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("queue:%d, ring_addr:%p\n", prio, desc));
+
+       /* init every desc in this ring */
+       if (rtlpriv->use_new_trx_flow == false) {
+               for (i = 0; i < entries; i++) {
+                       nextdescaddress = cpu_to_le32((u32) desc_dma +
+                                                     ((i +     1) % entries) *
+                                                     sizeof(*desc));
+
+                       rtlpriv->cfg->ops->set_desc(hw, (u8 *) & (desc[i]),
+                                                   true, 
+                                                   HW_DESC_TX_NEXTDESC_ADDR,
+                                                   (u8 *) & nextdescaddress);
+               }
+       }
+       return 0;
+}
+
+static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       int i;
+       
+       if (rtlpriv->use_new_trx_flow) {
+               struct rtl_rx_buffer_desc *entry = NULL;
+               /* alloc dma for this ring */
+               rtlpci->rx_ring[rxring_idx].buffer_desc = 
+                   pci_alloc_consistent(rtlpci->pdev,
+                                        sizeof(*rtlpci->rx_ring[rxring_idx].
+                                               buffer_desc) * 
+                                               rtlpci->rxringcount, 
+                                        &rtlpci->rx_ring[rxring_idx].dma);
+               if (!rtlpci->rx_ring[rxring_idx].buffer_desc ||
+                   (unsigned long)rtlpci->rx_ring[rxring_idx].buffer_desc & 0xFF) {
+                       RT_TRACE(COMP_ERR, DBG_EMERG, ("Cannot allocate RX ring\n"));
+                       return -ENOMEM;
+               }
+
+               memset(rtlpci->rx_ring[rxring_idx].buffer_desc, 0,
+                      sizeof(*rtlpci->rx_ring[rxring_idx].buffer_desc) *
+                      rtlpci->rxringcount);
+
+               /* init every desc in this ring */
+               rtlpci->rx_ring[rxring_idx].idx = 0;
+               for (i = 0; i < rtlpci->rxringcount; i++) {                     
+                       entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i];
+                       if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, 
+                                                     rxring_idx, i))
+                               return -ENOMEM;
+               }
+       } else {
+               struct rtl_rx_desc *entry = NULL;
+               u8 tmp_one = 1;
+               /* alloc dma for this ring */
+               rtlpci->rx_ring[rxring_idx].desc = 
+                   pci_alloc_consistent(rtlpci->pdev,
+                                        sizeof(*rtlpci->rx_ring[rxring_idx].
+                                               desc) * rtlpci->rxringcount, 
+                                        &rtlpci->rx_ring[rxring_idx].dma);
+               if (!rtlpci->rx_ring[rxring_idx].desc ||
+                   (unsigned long)rtlpci->rx_ring[rxring_idx].desc & 0xFF) {
+                       RT_TRACE(COMP_ERR, DBG_EMERG, 
+                                ("Cannot allocate RX ring\n"));
+                       return -ENOMEM;
+               }
+
+               memset(rtlpci->rx_ring[rxring_idx].desc, 0,
+                      sizeof(*rtlpci->rx_ring[rxring_idx].desc) *
+                      rtlpci->rxringcount);
+
+               /* init every desc in this ring */
+               rtlpci->rx_ring[rxring_idx].idx = 0;
+               for (i = 0; i < rtlpci->rxringcount; i++) {                     
+                       entry = &rtlpci->rx_ring[rxring_idx].desc[i];
+                       if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, 
+                                                     rxring_idx, i))
+                               return -ENOMEM;
+               }
+               rtlpriv->cfg->ops->set_desc(hw, (u8 *) entry, false,
+                                           HW_DESC_RXERO, (u8 *) & tmp_one);
+       }
+       return 0;
+}
+
+static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
+                                 unsigned int prio)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
+
+       /* free every desc in this ring */
+       while (skb_queue_len(&ring->queue)) {
+               u8 *entry;
+               struct sk_buff *skb = __skb_dequeue(&ring->queue);
+               if (rtlpriv->use_new_trx_flow)
+                       entry = (u8 *)(&ring->buffer_desc[ring->idx]);
+               else
+                       entry = (u8 *)(&ring->desc[ring->idx]);
+
+               pci_unmap_single(rtlpci->pdev,
+                                le32_to_cpu(rtlpriv->cfg->ops->get_desc(
+                                (u8 *) entry, true, HW_DESC_TXBUFF_ADDR)),
+                                skb->len, PCI_DMA_TODEVICE);
+               kfree_skb(skb);
+               ring->idx = (ring->idx + 1) % ring->entries;
+       }
+
+       /* free dma of this ring */
+       pci_free_consistent(rtlpci->pdev,
+                           sizeof(*ring->desc) * ring->entries,
+                           ring->desc, ring->dma);
+       ring->desc = NULL;
+       if (rtlpriv->use_new_trx_flow) {
+               pci_free_consistent(rtlpci->pdev,
+                                   sizeof(*ring->buffer_desc) * ring->entries,
+                                   ring->buffer_desc, ring->buffer_desc_dma);
+               ring->buffer_desc = NULL;
+       }       
+}
+
+static void _rtl_pci_free_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       int i;
+
+       /* free every desc in this ring */
+       for (i = 0; i < rtlpci->rxringcount; i++) {
+               struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[i];
+               if (!skb)
+                       continue;
+
+               pci_unmap_single(rtlpci->pdev, *((dma_addr_t *) skb->cb),
+                                rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
+               kfree_skb(skb);
+       }
+
+       /* free dma of this ring */
+       if (rtlpriv->use_new_trx_flow) {
+               pci_free_consistent(rtlpci->pdev,
+                                   sizeof(*rtlpci->rx_ring[rxring_idx].
+                                          buffer_desc) * rtlpci->rxringcount,
+                                   rtlpci->rx_ring[rxring_idx].buffer_desc,
+                                   rtlpci->rx_ring[rxring_idx].dma);
+               rtlpci->rx_ring[rxring_idx].buffer_desc = NULL;
+       } else {
+               pci_free_consistent(rtlpci->pdev,
+                                   sizeof(*rtlpci->rx_ring[rxring_idx].desc) *
+                                   rtlpci->rxringcount,
+                                   rtlpci->rx_ring[rxring_idx].desc,
+                                   rtlpci->rx_ring[rxring_idx].dma);
+               rtlpci->rx_ring[rxring_idx].desc = NULL;
+       }
+}
+
+static int _rtl_pci_init_trx_ring(struct ieee80211_hw *hw)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       int ret;
+       int i, rxring_idx;
+
+       /* rxring_idx 0:RX_MPDU_QUEUE
+        * rxring_idx 1:RX_CMD_QUEUE */
+       for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++) {
+               ret = _rtl_pci_init_rx_ring(hw, rxring_idx);
+               if (ret)
+                       return ret;
+       }
+
+       for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
+               ret = _rtl_pci_init_tx_ring(hw, i, rtlpci->txringcount[i]);
+               if (ret)
+                       goto err_free_rings;
+       }
+
+       return 0;
+
+err_free_rings:
+       for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++)
+               _rtl_pci_free_rx_ring(hw, rxring_idx);
+
+       for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
+               if (rtlpci->tx_ring[i].desc || 
+                   rtlpci->tx_ring[i].buffer_desc)
+                       _rtl_pci_free_tx_ring(hw, i);
+
+       return 1;
+}
+
+static int _rtl_pci_deinit_trx_ring(struct ieee80211_hw *hw)
+{
+       u32 i, rxring_idx;
+
+       /*free rx rings */
+       for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++)
+               _rtl_pci_free_rx_ring(hw, rxring_idx);
+
+       /*free tx rings */
+       for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
+               _rtl_pci_free_tx_ring(hw, i);
+
+       return 0;
+}
+
+int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       int i, rxring_idx;
+       unsigned long flags;
+       u8 tmp_one = 1;
+       /* rxring_idx 0:RX_MPDU_QUEUE */
+       /* rxring_idx 1:RX_CMD_QUEUE */
+       for (rxring_idx = 0; rxring_idx < RTL_PCI_MAX_RX_QUEUE; rxring_idx++) {
+               /* force the rx_ring[RX_MPDU_QUEUE/
+                * RX_CMD_QUEUE].idx to the first one */
+               /*new trx flow, do nothing*/
+               if ((rtlpriv->use_new_trx_flow == false) && 
+                    rtlpci->rx_ring[rxring_idx].desc) {
+                       struct rtl_rx_desc *entry = NULL;
+
+                       for (i = 0; i < rtlpci->rxringcount; i++) {
+                               entry = &rtlpci->rx_ring[rxring_idx].desc[i];                   
+                               rtlpriv->cfg->ops->set_desc(hw, (u8 *) entry, 
+                                                           false,
+                                                           HW_DESC_RXOWN, 
+                                                           (u8 *) & tmp_one);          
+                       }
+               }
+               rtlpci->rx_ring[rxring_idx].idx = 0;    }
+
+       /* after reset, release previous pending packet,
+        * and force the  tx idx to the first one */
+       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+       for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
+               if (rtlpci->tx_ring[i].desc || 
+                       rtlpci->tx_ring[i].buffer_desc) {
+                       struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i];
+
+                       while (skb_queue_len(&ring->queue)) {
+                               u8 *entry;
+                               struct sk_buff *skb = 
+                                       __skb_dequeue(&ring->queue);
+                               if (rtlpriv->use_new_trx_flow)
+                                       entry = (u8 *)(&ring->buffer_desc
+                                                               [ring->idx]);
+                               else
+                                       entry = (u8 *)(&ring->desc[ring->idx]);
+
+                               pci_unmap_single(rtlpci->pdev,
+                                       le32_to_cpu(rtlpriv->cfg->ops->get_desc(
+                                                       (u8 *)entry, true,
+                                                       HW_DESC_TXBUFF_ADDR)),
+                                       skb->len, PCI_DMA_TODEVICE);
+                               kfree_skb(skb);
+                               ring->idx = (ring->idx + 1) % ring->entries;
+                       }
+                       ring->idx = 0;
+               }
+       }
+
+       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+       return 0;
+}
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, 
+                                       struct sk_buff *skb)
+#else
+/*<delete in kernel end>*/
+static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw,
+                                       struct ieee80211_sta *sta,
+                                       struct sk_buff *skb)
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_sta *sta = info->control.sta;
+#endif
+/*<delete in kernel end>*/
+       struct rtl_sta_info *sta_entry = NULL;
+       u8 tid = rtl_get_tid(skb);
+       u16 fc = rtl_get_fc(skb);
+
+       if(!sta)
+               return false;
+       sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+
+       if (!rtlpriv->rtlhal.b_earlymode_enable)
+               return false;
+       if (ieee80211_is_nullfunc(fc))
+               return false;
+       if (ieee80211_is_qos_nullfunc(fc))
+               return false;
+       if (ieee80211_is_pspoll(fc)) {
+               return false;
+       }
+
+       if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL)
+               return false;
+       if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE)
+               return false;
+       if (tid > 7)
+               return false;
+       /* maybe every tid should be checked */
+       if (!rtlpriv->link_info.higher_busytxtraffic[tid])
+               return false;
+
+       spin_lock_bh(&rtlpriv->locks.waitq_lock);
+       skb_queue_tail(&rtlpriv->mac80211.skb_waitq[tid], skb);
+       spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+       return true;
+}
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+              struct rtl_tcb_desc *ptcb_desc)
+#else
+/*<delete in kernel end>*/
+static int rtl_pci_tx(struct ieee80211_hw *hw,
+                     struct ieee80211_sta *sta,
+                     struct sk_buff *skb,
+                     struct rtl_tcb_desc *ptcb_desc)
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_sta_info *sta_entry = NULL;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+       struct ieee80211_sta *sta = info->control.sta;
+#endif
+/*<delete in kernel end>*/
+       struct rtl8192_tx_ring *ring;
+       struct rtl_tx_desc *pdesc;
+       struct rtl_tx_buffer_desc *ptx_bd_desc = NULL;
+       u16 idx;
+       u8 own;
+       u8 temp_one = 1;
+       u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb);
+       unsigned long flags;
+       struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+       u16 fc = rtl_get_fc(skb);
+       u8 *pda_addr = hdr->addr1;
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       /*ssn */
+       u8 tid = 0;
+       u16 seq_number = 0;
+
+
+       if (ieee80211_is_mgmt(fc))
+               rtl_tx_mgmt_proc(hw, skb);
+
+       if (rtlpriv->psc.sw_ps_enabled) {
+               if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
+                   !ieee80211_has_pm(fc))
+                       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+       }
+
+       rtl_action_proc(hw, skb, true);
+
+       if (is_multicast_ether_addr(pda_addr))
+               rtlpriv->stats.txbytesmulticast += skb->len;
+       else if (is_broadcast_ether_addr(pda_addr))
+               rtlpriv->stats.txbytesbroadcast += skb->len;
+       else
+               rtlpriv->stats.txbytesunicast += skb->len;
+
+       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+       ring = &rtlpci->tx_ring[hw_queue];
+       if (hw_queue != BEACON_QUEUE) {
+               if (rtlpriv->use_new_trx_flow)
+                       idx = ring->cur_tx_wp;
+               else
+                       idx = (ring->idx + skb_queue_len(&ring->queue)) %
+                             ring->entries;
+       } else {
+               idx = 0;
+       }
+
+       pdesc = &ring->desc[idx];
+       
+       if (rtlpriv->use_new_trx_flow) {
+               ptx_bd_desc = &ring->buffer_desc[idx];
+       } else {        
+               own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
+                               true, HW_DESC_OWN);
+
+               if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
+                       RT_TRACE(COMP_ERR, DBG_WARNING,
+                                ("No more TX desc@%d, ring->idx = %d,"
+                                 "idx = %d, skb_queue_len = 0x%d\n",
+                                 hw_queue, ring->idx, idx,
+                                 skb_queue_len(&ring->queue)));
+
+                       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, 
+                                              flags);
+                       return skb->len;
+               }
+       }
+       
+       if (ieee80211_is_data_qos(fc)) {
+               tid = rtl_get_tid(skb);
+               if (sta) {
+                       sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+                       seq_number = (le16_to_cpu(hdr->seq_ctrl) & 
+                                     IEEE80211_SCTL_SEQ) >> 4;
+                       seq_number += 1;
+
+                       if (!ieee80211_has_morefrags(hdr->frame_control))
+                               sta_entry->tids[tid].seq_number = seq_number;
+               }
+       }
+
+       if (ieee80211_is_data(fc))
+               rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+       rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, 
+                                       (u8 *)ptx_bd_desc, info, skb, 
+                                       hw_queue, ptcb_desc);
+#else
+/*<delete in kernel end>*/
+       rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, 
+                                       (u8 *)ptx_bd_desc, info, sta, skb, 
+                                       hw_queue, ptcb_desc);
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+
+       __skb_queue_tail(&ring->queue, skb);
+       if (rtlpriv->use_new_trx_flow) {
+               rtlpriv->cfg->ops->set_desc(hw, (u8 *) pdesc, true,
+                                           HW_DESC_OWN, (u8 *) & hw_queue);
+       } else {
+               rtlpriv->cfg->ops->set_desc(hw, (u8 *) pdesc, true,
+                                           HW_DESC_OWN, (u8 *) & temp_one);
+       }
+
+       if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
+           hw_queue != BEACON_QUEUE) {
+
+               RT_TRACE(COMP_ERR, DBG_LOUD,
+                        ("less desc left, stop skb_queue@%d, "
+                         "ring->idx = %d,"
+                         "idx = %d, skb_queue_len = 0x%d\n",
+                         hw_queue, ring->idx, idx,
+                         skb_queue_len(&ring->queue)));
+
+               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
+       }
+
+       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+       rtlpriv->cfg->ops->tx_polling(hw, hw_queue);
+
+       return 0;
+}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+static void rtl_pci_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
+#else
+static void rtl_pci_flush(struct ieee80211_hw *hw, bool drop)
+#endif
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u16 i = 0;
+       int queue_id;
+       struct rtl8192_tx_ring *ring;
+       
+       if (mac->skip_scan)
+               return;
+       
+       for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) {
+               u32 queue_len;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+               if (((queues >> queue_id) & 0x1) == 0) {
+                       queue_id--;
+                       continue;
+               }
+#endif
+               ring = &pcipriv->dev.tx_ring[queue_id];
+               queue_len = skb_queue_len(&ring->queue);
+               if (queue_len == 0 || queue_id == BEACON_QUEUE ||
+                       queue_id == TXCMD_QUEUE) {
+                       queue_id--;
+                       continue;
+               } else {
+                       msleep(5);
+                       i++;
+               }
+
+               /* we just wait 1s for all queues */
+               if (rtlpriv->psc.rfpwr_state == ERFOFF ||
+                       is_hal_stop(rtlhal) || i >= 200)
+                       return;
+       }
+}
+
+void rtl_pci_deinit(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       _rtl_pci_deinit_trx_ring(hw);
+
+       synchronize_irq(rtlpci->pdev->irq);
+       tasklet_kill(&rtlpriv->works.irq_tasklet);
+
+       flush_workqueue(rtlpriv->works.rtl_wq);
+       destroy_workqueue(rtlpriv->works.rtl_wq);
+
+}
+
+int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int err;
+
+       _rtl_pci_init_struct(hw, pdev);
+
+       err = _rtl_pci_init_trx_ring(hw);
+       if (err) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("tx ring initialization failed"));
+               return err;
+       }
+
+       return 1;
+}
+
+int rtl_pci_start(struct ieee80211_hw *hw)
+{
+       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));
+
+       int err = 0;
+       RT_TRACE(COMP_INIT, DBG_DMESG, (" rtl_pci_start \n"));
+       rtl_pci_reset_trx_ring(hw);
+
+       rtlpriv->rtlhal.driver_is_goingto_unload = false;
+       err = rtlpriv->cfg->ops->hw_init(hw);
+       if (err) {
+               RT_TRACE(COMP_INIT, DBG_DMESG,
+                        ("Failed to config hardware err %x!\n",err));
+               return err;
+       }
+
+       rtlpriv->cfg->ops->enable_interrupt(hw);
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n"));
+
+       rtl_init_rx_config(hw);
+
+       /*should after adapter start and interrupt enable. */
+       set_hal_start(rtlhal);
+
+       RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+       rtlpriv->rtlhal.up_first_time = false;
+
+       RT_TRACE(COMP_INIT, DBG_DMESG, ("rtl_pci_start OK\n"));
+       return 0;
+}
+
+void rtl_pci_stop(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 RFInProgressTimeOut = 0;
+
+       /*
+        *should before disable interrrupt&adapter
+        *and will do it immediately.
+        */
+       set_hal_stop(rtlhal);
+
+       rtlpriv->cfg->ops->disable_interrupt(hw);
+
+       spin_lock(&rtlpriv->locks.rf_ps_lock);
+       while (ppsc->rfchange_inprogress) {
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
+               if (RFInProgressTimeOut > 100) {
+                       spin_lock(&rtlpriv->locks.rf_ps_lock);
+                       break;
+               }
+               mdelay(1);
+               RFInProgressTimeOut++;
+               spin_lock(&rtlpriv->locks.rf_ps_lock);
+       }
+       ppsc->rfchange_inprogress = true;
+       spin_unlock(&rtlpriv->locks.rf_ps_lock);
+
+       rtlpriv->rtlhal.driver_is_goingto_unload = true;
+       rtlpriv->cfg->ops->hw_disable(hw);
+       rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+
+       spin_lock(&rtlpriv->locks.rf_ps_lock);
+       ppsc->rfchange_inprogress = false;
+       spin_unlock(&rtlpriv->locks.rf_ps_lock);
+
+       rtl_pci_enable_aspm(hw);
+}
+
+static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
+                                 struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct pci_dev *bridge_pdev = pdev->bus->self;
+       u16 venderid;
+       u16 deviceid;
+       u8 revisionid;
+       u16 irqline;
+       u8 tmp;
+
+       venderid = pdev->vendor;
+       deviceid = pdev->device;
+       pci_read_config_byte(pdev, 0x8, &revisionid);
+       pci_read_config_word(pdev, 0x3C, &irqline);
+
+       if (deviceid == RTL_PCI_8192_DID ||
+           deviceid == RTL_PCI_0044_DID ||
+           deviceid == RTL_PCI_0047_DID ||
+           deviceid == RTL_PCI_8192SE_DID ||
+           deviceid == RTL_PCI_8174_DID ||
+           deviceid == RTL_PCI_8173_DID ||
+           deviceid == RTL_PCI_8172_DID ||
+           deviceid == RTL_PCI_8171_DID) {
+               switch (revisionid) {
+               case RTL_PCI_REVISION_ID_8192PCIE:
+                       RT_TRACE(COMP_INIT, DBG_DMESG,
+                                ("8192E is found but not supported now-"
+                                 "vid/did=%x/%x\n", venderid, deviceid));
+                       rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
+                       return false;
+                       break;
+               case RTL_PCI_REVISION_ID_8192SE:
+                       RT_TRACE(COMP_INIT, DBG_DMESG,
+                                ("8192SE is found - "
+                                 "vid/did=%x/%x\n", venderid, deviceid));
+                       rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
+                       break;
+               default:
+                       RT_TRACE(COMP_ERR, DBG_WARNING,
+                                ("Err: Unknown device - "
+                                 "vid/did=%x/%x\n", venderid, deviceid));
+                       rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
+                       break;
+
+               }
+       }else if(deviceid == RTL_PCI_8723AE_DID) {
+               rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE;
+               RT_TRACE(COMP_INIT, DBG_DMESG,
+                        ("8723AE PCI-E is found - "
+                         "vid/did=%x/%x\n", venderid, deviceid));
+       } else if (deviceid == RTL_PCI_8192CET_DID ||
+                  deviceid == RTL_PCI_8192CE_DID ||
+                  deviceid == RTL_PCI_8191CE_DID ||
+                  deviceid == RTL_PCI_8188CE_DID) {
+               rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE;
+               RT_TRACE(COMP_INIT, DBG_DMESG,
+                        ("8192C PCI-E is found - "
+                         "vid/did=%x/%x\n", venderid, deviceid));
+       } else if (deviceid == RTL_PCI_8192DE_DID ||
+                  deviceid == RTL_PCI_8192DE_DID2) {
+               rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE;
+               RT_TRACE(COMP_INIT, DBG_DMESG,
+                        ("8192D PCI-E is found - "
+                         "vid/did=%x/%x\n", venderid, deviceid));
+       }else if(deviceid == RTL_PCI_8188EE_DID){
+                       rtlhal->hw_type = HARDWARE_TYPE_RTL8188EE;
+                       RT_TRACE(COMP_INIT,DBG_LOUD,
+                                ("Find adapter, Hardware type is 8188EE\n"));
+       }else if (deviceid == RTL_PCI_8723BE_DID){
+                       rtlhal->hw_type = HARDWARE_TYPE_RTL8723BE;
+                       RT_TRACE(COMP_INIT,DBG_LOUD,
+                                ("Find adapter, Hardware type is 8723BE\n"));
+       }else if (deviceid == RTL_PCI_8192EE_DID){
+                       rtlhal->hw_type = HARDWARE_TYPE_RTL8192EE;
+                       RT_TRACE(COMP_INIT,DBG_LOUD,
+                                ("Find adapter, Hardware type is 8192EE\n"));
+       }else if (deviceid == RTL_PCI_8821AE_DID) {
+                       rtlhal->hw_type = HARDWARE_TYPE_RTL8821AE;
+                       RT_TRACE(COMP_INIT,DBG_LOUD,
+                               ("Find adapter, Hardware type is 8821AE\n"));
+       }else if (deviceid == RTL_PCI_8812AE_DID) {
+                       rtlhal->hw_type = HARDWARE_TYPE_RTL8812AE;
+                       RT_TRACE(COMP_INIT,DBG_LOUD,
+                               ("Find adapter, Hardware type is 8812AE\n"));
+       }else {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("Err: Unknown device -"
+                         " vid/did=%x/%x\n", venderid, deviceid));
+
+               rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
+       }
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) {
+               if (revisionid == 0 || revisionid == 1) {
+                       if (revisionid == 0) {
+                               RT_TRACE(COMP_INIT, DBG_LOUD,
+                                        ("Find 92DE MAC0.\n"));
+                               rtlhal->interfaceindex = 0;
+                       } else if (revisionid == 1) {
+                               RT_TRACE(COMP_INIT, DBG_LOUD,
+                                        ("Find 92DE MAC1.\n"));
+                               rtlhal->interfaceindex = 1;
+                       }
+               } else {
+                       RT_TRACE(COMP_INIT, DBG_LOUD, ("Unknown device - "
+                                "VendorID/DeviceID=%x/%x, Revision=%x\n",
+                                venderid, deviceid, revisionid));
+                       rtlhal->interfaceindex = 0;
+               }
+       }
+       
+       /* 92ee use new trx flow */
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192EE)
+               rtlpriv->use_new_trx_flow = true;
+       else
+               rtlpriv->use_new_trx_flow = false;
+       
+       /*find bus info */
+       pcipriv->ndis_adapter.busnumber = pdev->bus->number;
+       pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
+       pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn);
+
+       /*find bridge info */
+       pcipriv->ndis_adapter.pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN;
+       /* some ARM have no bridge_pdev and will crash here 
+        * so we should check if bridge_pdev is NULL */
+       if (bridge_pdev) {
+               pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor;
+               for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) {
+                       if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
+                               pcipriv->ndis_adapter.pcibridge_vendor = tmp;
+                               RT_TRACE(COMP_INIT, DBG_DMESG,
+                                        ("Pci Bridge Vendor is found index: %d\n",
+                                         tmp));
+                               break;
+                       }
+               }
+       }
+
+       if (pcipriv->ndis_adapter.pcibridge_vendor !=
+           PCI_BRIDGE_VENDOR_UNKNOWN) {
+               pcipriv->ndis_adapter.pcibridge_busnum =
+                   bridge_pdev->bus->number;
+               pcipriv->ndis_adapter.pcibridge_devnum =
+                   PCI_SLOT(bridge_pdev->devfn);
+               pcipriv->ndis_adapter.pcibridge_funcnum =
+                   PCI_FUNC(bridge_pdev->devfn);
+               pcipriv->ndis_adapter.pcicfg_addrport =
+                   (pcipriv->ndis_adapter.pcibridge_busnum << 16) |
+                   (pcipriv->ndis_adapter.pcibridge_devnum << 11) |
+                   (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+/*<delete in kernel end>*/
+               pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
+                   pci_pcie_cap(bridge_pdev);
+/*<delete in kernel start>*/
+#else
+               pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
+                       _rtl_pci_get_pciehdr_offset(hw);
+#endif
+/*<delete in kernel end>*/
+               pcipriv->ndis_adapter.num4bytes =
+                   (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;
+
+               rtl_pci_get_linkcontrol_field(hw);
+
+               if (pcipriv->ndis_adapter.pcibridge_vendor ==
+                   PCI_BRIDGE_VENDOR_AMD) {
+                       pcipriv->ndis_adapter.amd_l1_patch =
+                           rtl_pci_get_amd_l1_patch(hw);
+               }
+       }
+
+       RT_TRACE(COMP_INIT, DBG_DMESG,
+                ("pcidev busnumber:devnumber:funcnumber:"
+                 "vendor:link_ctl %d:%d:%d:%x:%x\n",
+                 pcipriv->ndis_adapter.busnumber,
+                 pcipriv->ndis_adapter.devnumber,
+                 pcipriv->ndis_adapter.funcnumber,
+                 pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg));
+
+       RT_TRACE(COMP_INIT, DBG_DMESG,
+                ("pci_bridge busnumber:devnumber:funcnumber:vendor:"
+                 "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
+                 pcipriv->ndis_adapter.pcibridge_busnum,
+                 pcipriv->ndis_adapter.pcibridge_devnum,
+                 pcipriv->ndis_adapter.pcibridge_funcnum,
+                 pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
+                 pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
+                 pcipriv->ndis_adapter.pcibridge_linkctrlreg,
+                 pcipriv->ndis_adapter.amd_l1_patch));
+
+       rtl_pci_parse_configuration(pdev, hw);
+       list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list);
+       return true;
+}
+
+static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+       int ret;
+       ret = pci_enable_msi(rtlpci->pdev);
+       if (ret < 0)
+               return ret;
+
+       ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
+                         IRQF_SHARED, KBUILD_MODNAME, hw);
+       if (ret < 0) {
+               pci_disable_msi(rtlpci->pdev);
+               return ret;
+       }
+
+       rtlpci->using_msi = true;
+       
+       RT_TRACE(COMP_INIT|COMP_INTR, DBG_DMESG, ("MSI Interrupt Mode!\n"));
+       return 0;
+}
+
+static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+       int ret;
+       
+       ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
+                         IRQF_SHARED, KBUILD_MODNAME, hw);
+       if (ret < 0) {
+               return ret;
+       }
+
+       rtlpci->using_msi = false;
+       RT_TRACE(COMP_INIT|COMP_INTR, DBG_DMESG, 
+                ("Pin-based Interrupt Mode!\n"));
+       return 0;
+}
+
+static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+       int ret;
+       if (rtlpci->msi_support == true) {
+               ret = rtl_pci_intr_mode_msi(hw);
+               if (ret < 0)
+                       ret = rtl_pci_intr_mode_legacy(hw);
+       } else {
+               ret = rtl_pci_intr_mode_legacy(hw);
+       }
+       return ret;
+}
+
+/* this is used for other modules get
+ * hw pointer in rtl_pci_get_hw_pointer */
+struct ieee80211_hw *hw_export = NULL;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+int rtl_pci_probe(struct pci_dev *pdev,
+                  const struct pci_device_id *id)
+
+#else
+int __devinit rtl_pci_probe(struct pci_dev *pdev,
+                           const struct pci_device_id *id)
+#endif
+{
+       struct ieee80211_hw *hw = NULL;
+
+       struct rtl_priv *rtlpriv = NULL;
+       struct rtl_pci_priv *pcipriv = NULL;
+       struct rtl_pci *rtlpci;
+       unsigned long pmem_start, pmem_len, pmem_flags;
+       int err;
+
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               RT_ASSERT(false,
+                         ("%s : Cannot enable new PCI device\n",
+                          pci_name(pdev)));
+               return err;
+       }
+
+       if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+               if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+                       RT_ASSERT(false, ("Unable to obtain 32bit DMA "
+                                         "for consistent allocations\n"));
+                       pci_disable_device(pdev);
+                       return -ENOMEM;
+               }
+       }
+
+       pci_set_master(pdev);
+
+       hw = ieee80211_alloc_hw(sizeof(struct rtl_pci_priv) +
+                               sizeof(struct rtl_priv), &rtl_ops);
+       if (!hw) {
+               RT_ASSERT(false,
+                         ("%s : ieee80211 alloc failed\n", pci_name(pdev)));
+               err = -ENOMEM;
+               goto fail1;
+       }
+       hw_export = hw;
+
+       SET_IEEE80211_DEV(hw, &pdev->dev);
+       pci_set_drvdata(pdev, hw);
+
+       rtlpriv = hw->priv;
+       pcipriv = (void *)rtlpriv->priv;
+       pcipriv->dev.pdev = pdev;
+
+       /* init cfg & intf_ops */
+       rtlpriv->rtlhal.interface = INTF_PCI;
+       rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
+       rtlpriv->intf_ops = &rtl_pci_ops;
+       rtlpriv->glb_var = &global_var;
+
+       /*
+        *init dbgp flags before all
+        *other functions, because we will
+        *use it in other funtions like
+        *RT_TRACE/RT_PRINT/RTL_PRINT_DATA
+        *you can not use these macro
+        *before this
+        */
+       rtl_dbgp_flag_init(hw);
+
+       /* MEM map */
+       err = pci_request_regions(pdev, KBUILD_MODNAME);
+       if (err) {
+               RT_ASSERT(false, ("Can't obtain PCI resources\n"));
+               return err;
+       }
+
+       pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
+       pmem_len = pci_resource_len(pdev, rtlpriv->cfg->bar_id);
+       pmem_flags = pci_resource_flags(pdev, rtlpriv->cfg->bar_id);
+
+       /*shared mem start */
+       rtlpriv->io.pci_mem_start =
+                       (unsigned long)pci_iomap(pdev,
+                       rtlpriv->cfg->bar_id, pmem_len);
+       if (rtlpriv->io.pci_mem_start == 0) {
+               RT_ASSERT(false, ("Can't map PCI mem\n"));
+               goto fail2;
+       }
+
+       RT_TRACE(COMP_INIT, DBG_DMESG,
+                ("mem mapped space: start: 0x%08lx len:%08lx "
+                 "flags:%08lx, after map:0x%08lx\n",
+                 pmem_start, pmem_len, pmem_flags,
+                 rtlpriv->io.pci_mem_start));
+
+       /* Disable Clk Request */
+       pci_write_config_byte(pdev, 0x81, 0);
+       /* leave D3 mode */
+       pci_write_config_byte(pdev, 0x44, 0);
+       pci_write_config_byte(pdev, 0x04, 0x06);
+       pci_write_config_byte(pdev, 0x04, 0x07);
+
+       /* find adapter */
+       /* if chip not support, will return false */
+       if(!_rtl_pci_find_adapter(pdev, hw))
+               goto fail3;
+
+       /* Init IO handler */
+       _rtl_pci_io_handler_init(&pdev->dev, hw);
+
+       /*like read eeprom and so on */
+       rtlpriv->cfg->ops->read_eeprom_info(hw);
+
+       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("Can't init_sw_vars.\n"));
+               goto fail3;
+       }
+
+       rtlpriv->cfg->ops->init_sw_leds(hw);
+
+       /*aspm */
+       rtl_pci_init_aspm(hw);
+
+       /* Init mac80211 sw */
+       err = rtl_init_core(hw);
+       if (err) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Can't allocate sw for mac80211.\n"));
+               goto fail3;
+       }
+
+       /* Init PCI sw */
+       err = !rtl_pci_init(hw, pdev);
+       if (err) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("Failed to init PCI.\n"));
+               goto fail3;
+       }
+
+       err = ieee80211_register_hw(hw);
+       if (err) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Can't register mac80211 hw.\n"));
+               goto fail3;
+       } else {
+               rtlpriv->mac80211.mac80211_registered = 1;
+       }
+       /* the wiphy must have been registed to 
+        * cfg80211 prior to regulatory_hint */
+       if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) {
+               RT_TRACE(COMP_ERR, DBG_WARNING, ("regulatory_hint fail\n"));
+       }
+
+       err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
+       if (err) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("failed to create sysfs device attributes\n"));
+               goto fail3;
+       }
+       /* add for prov */
+       rtl_proc_add_one(hw);
+
+       /*init rfkill */
+       rtl_init_rfkill(hw);
+
+       rtlpci = rtl_pcidev(pcipriv);
+
+       err = rtl_pci_intr_mode_decide(hw);
+       if (err) {
+               RT_TRACE(COMP_INIT, DBG_DMESG,
+                        ("%s: failed to register IRQ handler\n",
+                         wiphy_name(hw->wiphy)));
+               goto fail3;
+       } else {
+               rtlpci->irq_alloc = 1;
+       }
+
+       set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+       return 0;
+
+fail3:
+       pci_set_drvdata(pdev, NULL);
+       rtl_deinit_core(hw);
+       ieee80211_free_hw(hw);
+
+       if (rtlpriv->io.pci_mem_start != 0)
+               pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+
+fail2:
+       pci_release_regions(pdev);
+
+fail1:
+
+       pci_disable_device(pdev);
+
+       return -ENODEV;
+
+}
+//EXPORT_SYMBOL(rtl_pci_probe);
+
+struct ieee80211_hw *rtl_pci_get_hw_pointer(void)
+{
+       return hw_export;
+}
+//EXPORT_SYMBOL(rtl_pci_get_hw_pointer);
+
+void rtl_pci_disconnect(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+       struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
+
+       clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+       sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
+
+       /* add for prov */
+       rtl_proc_remove_one(hw);
+       
+
+       /*ieee80211_unregister_hw will call ops_stop */
+       if (rtlmac->mac80211_registered == 1) {
+               ieee80211_unregister_hw(hw);
+               rtlmac->mac80211_registered = 0;
+       } else {
+               rtl_deinit_deferred_work(hw);
+               rtlpriv->intf_ops->adapter_stop(hw);
+       }
+
+       /*deinit rfkill */
+       rtl_deinit_rfkill(hw);
+
+       rtl_pci_deinit(hw);
+       rtl_deinit_core(hw);
+       rtlpriv->cfg->ops->deinit_sw_vars(hw);
+
+       if (rtlpci->irq_alloc) {
+               synchronize_irq(rtlpci->pdev->irq);
+               free_irq(rtlpci->pdev->irq, hw);
+               rtlpci->irq_alloc = 0;
+       }
+
+       if (rtlpci->using_msi == true)
+               pci_disable_msi(rtlpci->pdev);
+
+       list_del(&rtlpriv->list);
+       if (rtlpriv->io.pci_mem_start != 0) {
+               pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+               pci_release_regions(pdev);
+       }
+
+       pci_disable_device(pdev);
+
+       rtl_pci_disable_aspm(hw);
+
+       pci_set_drvdata(pdev, NULL);
+
+       ieee80211_free_hw(hw);
+}
+//EXPORT_SYMBOL(rtl_pci_disconnect);
+
+/***************************************
+kernel pci power state define:
+PCI_D0         ((pci_power_t __force) 0)
+PCI_D1         ((pci_power_t __force) 1)
+PCI_D2         ((pci_power_t __force) 2)
+PCI_D3hot      ((pci_power_t __force) 3)
+PCI_D3cold     ((pci_power_t __force) 4)
+PCI_UNKNOWN    ((pci_power_t __force) 5)
+
+This function is called when system
+goes into suspend state mac80211 will
+call rtl_mac_stop() from the mac80211
+suspend function first, So there is
+no need to call hw_disable here.
+****************************************/
+int rtl_pci_suspend(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->cfg->ops->hw_suspend(hw);
+       rtl_deinit_rfkill(hw);
+
+       return 0;
+}
+//EXPORT_SYMBOL(rtl_pci_suspend);
+
+int rtl_pci_resume(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->cfg->ops->hw_resume(hw);
+       rtl_init_rfkill(hw);
+       
+       return 0;
+}
+//EXPORT_SYMBOL(rtl_pci_resume);
+
+struct rtl_intf_ops rtl_pci_ops = {
+       .read_efuse_byte = read_efuse_byte,
+       .adapter_start = rtl_pci_start,
+       .adapter_stop = rtl_pci_stop,
+       .check_buddy_priv = rtl_pci_check_buddy_priv,
+       .adapter_tx = rtl_pci_tx,
+       .flush = rtl_pci_flush,
+       .reset_trx_ring = rtl_pci_reset_trx_ring,
+       .waitq_insert = rtl_pci_tx_chk_waitq_insert,
+
+       .disable_aspm = rtl_pci_disable_aspm,
+       .enable_aspm = rtl_pci_enable_aspm,
+};
diff --git a/drivers/staging/rtl8821ae/pci.h b/drivers/staging/rtl8821ae/pci.h
new file mode 100644 (file)
index 0000000..9f20655
--- /dev/null
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ * 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_PCI_H__
+#define __RTL_PCI_H__
+
+#include <linux/pci.h>
+/*
+1: MSDU packet queue,
+2: Rx Command Queue
+*/
+#define RTL_PCI_RX_MPDU_QUEUE                  0
+#define RTL_PCI_RX_CMD_QUEUE                   1
+#define RTL_PCI_MAX_RX_QUEUE                   2
+
+#define RTL_PCI_MAX_RX_COUNT                   512//64
+#define RTL_PCI_MAX_TX_QUEUE_COUNT             9
+
+#define RT_TXDESC_NUM                          128
+#define TX_DESC_NUM_92E                                512
+#define RT_TXDESC_NUM_BE_QUEUE                 256
+
+#define BK_QUEUE                               0
+#define BE_QUEUE                               1
+#define VI_QUEUE                               2
+#define VO_QUEUE                               3
+#define BEACON_QUEUE                           4
+#define TXCMD_QUEUE                            5
+#define MGNT_QUEUE                             6
+#define HIGH_QUEUE                             7
+#define HCCA_QUEUE                             8
+
+#define RTL_PCI_DEVICE(vend, dev, cfg)  \
+       .vendor = (vend), \
+       .device = (dev), \
+       .subvendor = PCI_ANY_ID, \
+       .subdevice = PCI_ANY_ID,\
+       .driver_data = (kernel_ulong_t)&(cfg)
+
+#define INTEL_VENDOR_ID                                0x8086
+#define SIS_VENDOR_ID                          0x1039
+#define ATI_VENDOR_ID                          0x1002
+#define ATI_DEVICE_ID                          0x7914
+#define AMD_VENDOR_ID                          0x1022
+
+#define PCI_MAX_BRIDGE_NUMBER                  255
+#define PCI_MAX_DEVICES                                32
+#define PCI_MAX_FUNCTION                       8
+
+#define PCI_CONF_ADDRESS       0x0CF8  /*PCI Configuration Space Address */
+#define PCI_CONF_DATA          0x0CFC  /*PCI Configuration Space Data */
+
+#define PCI_CLASS_BRIDGE_DEV           0x06
+#define PCI_SUBCLASS_BR_PCI_TO_PCI     0x04
+#define PCI_CAPABILITY_ID_PCI_EXPRESS  0x10
+#define PCI_CAP_ID_EXP                 0x10
+
+#define U1DONTCARE                     0xFF
+#define U2DONTCARE                     0xFFFF
+#define U4DONTCARE                     0xFFFFFFFF
+
+#define RTL_PCI_8192_DID       0x8192  /*8192 PCI-E */
+#define RTL_PCI_8192SE_DID     0x8192  /*8192 SE */
+#define RTL_PCI_8174_DID       0x8174  /*8192 SE */
+#define RTL_PCI_8173_DID       0x8173  /*8191 SE Crab */
+#define RTL_PCI_8172_DID       0x8172  /*8191 SE RE */
+#define RTL_PCI_8171_DID       0x8171  /*8191 SE Unicron */
+#define RTL_PCI_0045_DID       0x0045  /*8190 PCI for Ceraga */
+#define RTL_PCI_0046_DID       0x0046  /*8190 Cardbus for Ceraga */
+#define RTL_PCI_0044_DID       0x0044  /*8192e PCIE for Ceraga */
+#define RTL_PCI_0047_DID       0x0047  /*8192e Express Card for Ceraga */
+#define RTL_PCI_700F_DID       0x700F
+#define RTL_PCI_701F_DID       0x701F
+#define RTL_PCI_DLINK_DID      0x3304
+#define RTL_PCI_8723AE_DID     0x8723  /*8723e */
+#define RTL_PCI_8192CET_DID    0x8191  /*8192ce */
+#define RTL_PCI_8192CE_DID     0x8178  /*8192ce */
+#define RTL_PCI_8191CE_DID     0x8177  /*8192ce */
+#define RTL_PCI_8188CE_DID     0x8176  /*8192ce */
+#define RTL_PCI_8192CU_DID     0x8191  /*8192ce */
+#define RTL_PCI_8192DE_DID     0x8193  /*8192de */
+#define RTL_PCI_8192DE_DID2    0x002B  /*92DE*/
+#define RTL_PCI_8188EE_DID     0x8179  /*8188ee*/
+#define RTL_PCI_8723BE_DID     0xB723  /*8723be*/
+#define RTL_PCI_8192EE_DID     0x818B  /*8192ee*/
+#define RTL_PCI_8821AE_DID     0x8821  /*8821ae*/
+#define RTL_PCI_8812AE_DID     0x8812  /*8812ae*/
+
+/*8192 support 16 pages of IO registers*/
+#define RTL_MEM_MAPPED_IO_RANGE_8190PCI        0x1000
+#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE       0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192SE         0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192CE         0x4000
+#define RTL_MEM_MAPPED_IO_RANGE_8192DE         0x4000
+
+#define RTL_PCI_REVISION_ID_8190PCI            0x00
+#define RTL_PCI_REVISION_ID_8192PCIE           0x01
+#define RTL_PCI_REVISION_ID_8192SE             0x10
+#define RTL_PCI_REVISION_ID_8192CE             0x1
+#define RTL_PCI_REVISION_ID_8192DE             0x0
+
+#define PCI_VENDOR_ID_REALTEK          0x10ec
+
+#define RTL_DEFAULT_HARDWARE_TYPE      HARDWARE_TYPE_RTL8192CE
+
+enum pci_bridge_vendor {
+       PCI_BRIDGE_VENDOR_INTEL = 0x0,  /*0b'0000,0001 */
+       PCI_BRIDGE_VENDOR_ATI,          /*0b'0000,0010*/
+       PCI_BRIDGE_VENDOR_AMD,          /*0b'0000,0100*/
+       PCI_BRIDGE_VENDOR_SIS,          /*0b'0000,1000*/
+       PCI_BRIDGE_VENDOR_UNKNOWN,      /*0b'0100,0000*/
+       PCI_BRIDGE_VENDOR_MAX,  
+};
+
+struct rtl_pci_capabilities_header {
+    u8 capability_id;
+    u8 next;
+};
+
+/* In new TRX flow, Buffer_desc is new concept 
+  * But TX wifi info == TX descriptor in old flow
+  * RX wifi info == RX descriptor in old flow */
+struct rtl_tx_buffer_desc {
+#if (RTL8192EE_SEG_NUM == 2)
+       u32 dword[2*(DMA_IS_64BIT + 1)*8]; //seg = 8
+#elif (RTL8192EE_SEG_NUM == 1)
+       u32 dword[2*(DMA_IS_64BIT + 1)*4]; //seg = 4
+#elif (RTL8192EE_SEG_NUM == 0)
+       u32 dword[2*(DMA_IS_64BIT + 1)*2]; //seg = 2
+#endif
+} __packed;
+
+struct rtl_tx_desc {/*old: tx desc*//*new: tx wifi info*/
+       u32 dword[16];
+} __packed;
+
+struct rtl_rx_buffer_desc { /*rx buffer desc*/
+       u32 dword[2];
+} __packed;
+
+struct rtl_rx_desc { /*old: rx desc*//*new: rx wifi info*/
+       u32 dword[8];
+} __packed;
+
+struct rtl_tx_cmd_desc {
+       u32 dword[16];
+} __packed;
+
+struct rtl8192_tx_ring {
+       struct rtl_tx_desc *desc; /*tx desc / tx wifi info*/
+       dma_addr_t dma; /*tx desc dma memory / tx wifi info dma memory*/
+       unsigned int idx;
+       unsigned int entries;
+       struct sk_buff_head queue;
+       /*add for new trx flow*/
+       struct rtl_tx_buffer_desc *buffer_desc; /*tx buffer descriptor*/
+       dma_addr_t buffer_desc_dma; /*tx bufferd desc dma memory*/
+       u16 avl_desc; /* available_desc_to_write */
+       u16 cur_tx_wp; /* current_tx_write_point */
+       u16 cur_tx_rp; /* current_tx_read_point */
+};
+
+struct rtl8192_rx_ring {
+       struct rtl_rx_desc *desc;/*for old trx flow, not uesd in new trx*/
+       /*dma matches either 'desc' or 'buffer_desc'*/
+       dma_addr_t dma;
+       unsigned int idx;
+       struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT];
+       /*add for new trx flow*/
+       struct rtl_rx_buffer_desc *buffer_desc; /*rx buffer descriptor*/
+       u16 next_rx_rp; /* next_rx_read_point */
+};
+
+struct rtl_pci {
+       struct pci_dev *pdev;
+       bool irq_enabled;
+
+       /*Tx */
+       struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT];
+       int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT];
+       u32 transmit_config;
+
+       /*Rx */
+       struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE];
+       int rxringcount;
+       u16 rxbuffersize;
+       u32 receive_config;
+
+       /*irq */
+       u8 irq_alloc;
+       u32 irq_mask[2];
+       u32 sys_irq_mask;
+
+       /*Bcn control register setting */
+       u32 reg_bcn_ctrl_val;
+
+        /*ASPM*/ u8 const_pci_aspm;
+       u8 const_amdpci_aspm;
+       u8 const_hwsw_rfoff_d3;
+       u8 const_support_pciaspm;
+       /*pci-e bridge */
+       u8 const_hostpci_aspm_setting;
+       /*pci-e device */
+       u8 const_devicepci_aspm_setting;
+       /*If it supports ASPM, Offset[560h] = 0x40,
+          otherwise Offset[560h] = 0x00. */
+       bool b_support_aspm;
+       bool b_support_backdoor;
+
+       /*QOS & EDCA */
+       enum acm_method acm_method;
+
+       u16 shortretry_limit;
+       u16 longretry_limit;
+       
+       /* MSI support */
+       bool msi_support;
+       bool using_msi;
+};
+
+struct mp_adapter {
+       u8 linkctrl_reg;
+
+       u8 busnumber;
+       u8 devnumber;
+       u8 funcnumber;
+
+       u8 pcibridge_busnum;
+       u8 pcibridge_devnum;
+       u8 pcibridge_funcnum;
+
+       u8 pcibridge_vendor;
+       u16 pcibridge_vendorid;
+       u16 pcibridge_deviceid;
+
+       u32 pcicfg_addrport;
+       u8 num4bytes;
+
+       u8 pcibridge_pciehdr_offset;
+       u8 pcibridge_linkctrlreg;
+
+       bool amd_l1_patch;
+};
+
+struct rtl_pci_priv {
+       struct rtl_pci dev;
+       struct mp_adapter ndis_adapter;
+       struct rtl_led_ctl ledctl;
+       struct bt_coexist_info btcoexist;
+};
+
+#define rtl_pcipriv(hw)                (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
+#define rtl_pcidev(pcipriv)    (&((pcipriv)->dev))
+
+int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
+
+extern struct rtl_intf_ops rtl_pci_ops;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+int rtl_pci_probe(struct pci_dev *pdev,
+                  const struct pci_device_id *id);
+#else
+int __devinit rtl_pci_probe(struct pci_dev *pdev,
+                           const struct pci_device_id *id);
+#endif
+void rtl_pci_disconnect(struct pci_dev *pdev);
+int rtl_pci_suspend(struct device *dev);
+int rtl_pci_resume(struct device *dev);
+
+static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+       return 0xff & readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+       return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
+{
+       return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
+{
+       writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write16_async(struct rtl_priv *rtlpriv,
+                                    u32 addr, u16 val)
+{
+       writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void pci_write32_async(struct rtl_priv *rtlpriv,
+                                    u32 addr, u32 val)
+{
+       writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
+}
+
+static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
+{
+       outl(val, port);
+}
+
+static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val)
+{
+       outb(val, port);
+}
+
+static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 * pval)
+{
+       *pval = inb(port);
+}
+
+static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 * pval)
+{
+       *pval = inw(port);
+}
+
+static inline void rtl_pci_raw_read_port_ulong(u32 port, u32 * pval)
+{
+       *pval = inl(port);
+}
+
+#endif
diff --git a/drivers/staging/rtl8821ae/ps.c b/drivers/staging/rtl8821ae/ps.c
new file mode 100644 (file)
index 0000000..6c86436
--- /dev/null
@@ -0,0 +1,1025 @@
+/******************************************************************************
+ *
+ * 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 "wifi.h"
+#include "base.h"
+#include "ps.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+#include <linux/export.h>
+#endif
+#include "btcoexist/rtl_btc.h"
+
+bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool init_status = true;
+
+       /*<1> reset trx ring */
+       if (rtlhal->interface == INTF_PCI)
+               rtlpriv->intf_ops->reset_trx_ring(hw);
+
+       if (is_hal_stop(rtlhal))
+               RT_TRACE(COMP_ERR, DBG_WARNING, ("Driver is already down!\n"));
+
+       /*<2> Enable Adapter */
+       rtlpriv->cfg->ops->hw_init(hw);
+       RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+       /*init_status = false; */
+
+       /*<3> Enable Interrupt */
+       rtlpriv->cfg->ops->enable_interrupt(hw);
+
+       /*<enable timer> */
+       rtl_watch_dog_timer_callback((unsigned long)hw);
+
+       return init_status;
+}
+//EXPORT_SYMBOL(rtl_ps_enable_nic);
+
+bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
+{
+       bool status = true;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       /*<1> Stop all timer */
+       rtl_deinit_deferred_work(hw);
+
+       /*<2> Disable Interrupt */
+       rtlpriv->cfg->ops->disable_interrupt(hw);
+
+       /*<3> Disable Adapter */
+       rtlpriv->cfg->ops->hw_disable(hw);
+
+       return status;
+}
+//EXPORT_SYMBOL(rtl_ps_disable_nic);
+
+bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
+                        enum rf_pwrstate state_toset,
+                        u32 changesource, bool protect_or_not)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       enum rf_pwrstate rtstate;
+       bool b_actionallowed = false;
+       u16 rfwait_cnt = 0;
+
+       /*protect_or_not = true; */
+
+       if (protect_or_not)
+               goto no_protect;
+
+       /*
+        *Only one thread can change
+        *the RF state at one time, and others
+        *should wait to be executed.
+        */
+       while (true) {
+               spin_lock(&rtlpriv->locks.rf_ps_lock);
+               if (ppsc->rfchange_inprogress) {
+                       spin_unlock(&rtlpriv->locks.rf_ps_lock);
+
+                       RT_TRACE(COMP_ERR, DBG_WARNING,
+                                ("RF Change in progress!"
+                                 "Wait to set..state_toset(%d).\n",
+                                 state_toset));
+
+                       /* Set RF after the previous action is done.  */
+                       while (ppsc->rfchange_inprogress) {
+                               rfwait_cnt++;
+                               mdelay(1);
+                               /*
+                                *Wait too long, return false to avoid
+                                *to be stuck here.
+                                */
+                               if (rfwait_cnt > 100)
+                                       return false;
+                       }
+               } else {
+                       ppsc->rfchange_inprogress = true;
+                       spin_unlock(&rtlpriv->locks.rf_ps_lock);
+                       break;
+               }
+       }
+
+no_protect:
+       rtstate = ppsc->rfpwr_state;
+
+       switch (state_toset) {
+       case ERFON:
+               ppsc->rfoff_reason &= (~changesource);
+
+               if ((changesource == RF_CHANGE_BY_HW) &&
+                   (ppsc->b_hwradiooff == true)) {
+                       ppsc->b_hwradiooff = false;
+               }
+
+               if (!ppsc->rfoff_reason) {
+                       ppsc->rfoff_reason = 0;
+                       b_actionallowed = true;
+               }
+
+               break;
+
+       case ERFOFF:
+
+               if ((changesource == RF_CHANGE_BY_HW) &&
+                   (ppsc->b_hwradiooff == false)) {
+                       ppsc->b_hwradiooff = true;
+               }
+
+               ppsc->rfoff_reason |= changesource;
+               b_actionallowed = true;
+               break;
+
+       case ERFSLEEP:
+               ppsc->rfoff_reason |= changesource;
+               b_actionallowed = true;
+               break;
+
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("switch case not process \n"));
+               break;
+       }
+
+       if (b_actionallowed)
+               rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
+
+       if (!protect_or_not) {
+               spin_lock(&rtlpriv->locks.rf_ps_lock);
+               ppsc->rfchange_inprogress = false;
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
+       }
+
+       return b_actionallowed;
+}
+//EXPORT_SYMBOL(rtl_ps_set_rf_state);
+
+static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
+{
+       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));
+
+       ppsc->b_swrf_processing = true;
+
+       if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) {
+               if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
+                   RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
+                   rtlhal->interface == INTF_PCI) {
+                       rtlpriv->intf_ops->disable_aspm(hw);
+                       RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+               }
+       }
+
+       if (rtlpriv->cfg->ops->get_btc_status()){
+               rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv,
+                                               ppsc->inactive_pwrstate);
+       }
+       rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate,
+                           RF_CHANGE_BY_IPS, false);
+
+       if (ppsc->inactive_pwrstate == ERFOFF &&
+           rtlhal->interface == INTF_PCI) {
+               if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+                   !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+                       rtlpriv->intf_ops->enable_aspm(hw);
+                       RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+               }
+       }
+
+       ppsc->b_swrf_processing = false;
+}
+
+void rtl_ips_nic_off_wq_callback(void *data)
+{
+       struct rtl_works *rtlworks =
+           container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_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));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       enum rf_pwrstate rtstate;
+
+       if (mac->opmode != NL80211_IFTYPE_STATION) {
+               RT_TRACE(COMP_ERR, DBG_WARNING, ("not station return\n"));
+               return;
+       }
+
+       if (mac->p2p_in_use)
+               return;
+
+       if (mac->link_state > MAC80211_NOLINK)
+               return;
+
+       if (is_hal_stop(rtlhal))
+               return;
+
+       if (rtlpriv->sec.being_setkey)
+               return;
+
+       if(rtlpriv->cfg->ops->bt_turn_off_bt_coexist_before_enter_lps)
+               rtlpriv->cfg->ops->bt_turn_off_bt_coexist_before_enter_lps(hw);
+
+       if (ppsc->b_inactiveps) {
+               rtstate = ppsc->rfpwr_state;
+
+               /*
+                *Do not enter IPS in the following conditions:
+                *(1) RF is already OFF or Sleep
+                *(2) b_swrf_processing (indicates the IPS is still under going)
+                *(3) Connectted (only disconnected can trigger IPS)
+                *(4) IBSS (send Beacon)
+                *(5) AP mode (send Beacon)
+                *(6) monitor mode (rcv packet)
+                */
+
+               if (rtstate == ERFON &&
+                   !ppsc->b_swrf_processing &&
+                   (mac->link_state == MAC80211_NOLINK) &&
+                   !mac->act_scanning) {
+                       RT_TRACE(COMP_RF, DBG_LOUD,
+                                ("IPSEnter(): Turn off RF.\n"));
+
+                       ppsc->inactive_pwrstate = ERFOFF;
+                       ppsc->b_in_powersavemode = true;
+
+                       /*rtl_pci_reset_trx_ring(hw); */
+                       _rtl_ps_inactive_ps(hw);
+               }
+       }
+}
+
+void rtl_ips_nic_off(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       /*
+        *because when link with ap, mac80211 will ask us
+        *to disable nic quickly after scan before linking,
+        *this will cause link failed, so we delay 100ms here
+        */
+       queue_delayed_work(rtlpriv->works.rtl_wq,
+                          &rtlpriv->works.ips_nic_off_wq, MSECS(100));
+}
+
+/* NOTICE: any opmode should exc nic_on, or disable without
+ * nic_on may something wrong, like adhoc TP*/
+void rtl_ips_nic_on(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       enum rf_pwrstate rtstate;
+
+       cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
+
+       spin_lock(&rtlpriv->locks.ips_lock);
+       if (ppsc->b_inactiveps) {
+               rtstate = ppsc->rfpwr_state;
+
+               if (rtstate != ERFON &&
+                   !ppsc->b_swrf_processing &&
+                   ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
+
+                       ppsc->inactive_pwrstate = ERFON;
+                       ppsc->b_in_powersavemode = false;
+                       _rtl_ps_inactive_ps(hw);
+               }
+       }
+       spin_unlock(&rtlpriv->locks.ips_lock);
+}
+
+/*for FW LPS*/
+
+/*
+ *Determine if we can set Fw into PS mode
+ *in current condition.Return true if it
+ *can enter PS mode.
+ */
+static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       u32 ps_timediff;
+
+       ps_timediff = jiffies_to_msecs(jiffies -
+                                      ppsc->last_delaylps_stamp_jiffies);
+
+       if (ps_timediff < 2000) {
+               RT_TRACE(COMP_POWER, DBG_LOUD,
+                        ("Delay enter Fw LPS for DHCP, ARP,"
+                         " or EAPOL exchanging state.\n"));
+               return false;
+       }
+
+       if (mac->link_state != MAC80211_LINKED)
+               return false;
+
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               return false;
+
+       return true;
+}
+
+/* Change current and default preamble mode.*/
+void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       bool enter_fwlps;
+
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               return;
+
+       if (mac->link_state != MAC80211_LINKED)
+               return;
+
+       if (ppsc->dot11_psmode == rt_psmode)
+               return;
+
+       /* Update power save mode configured. */
+       ppsc->dot11_psmode = rt_psmode;
+
+       /*
+        *<FW control LPS>
+        *1. Enter PS mode
+        *   Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
+        *   cmd to set Fw into PS mode.
+        *2. Leave PS mode
+        *   Send H2C fw_pwrmode cmd to Fw to set Fw into Active
+        *   mode and set RPWM to turn RF on.
+        */
+
+       if ((ppsc->b_fwctrl_lps) && ppsc->report_linked) {
+               if (ppsc->dot11_psmode == EACTIVE) {
+                       RT_TRACE(COMP_RF, DBG_DMESG,
+                                ("FW LPS leave ps_mode:%x\n",
+                                 FW_PS_ACTIVE_MODE));
+                       enter_fwlps = false;
+                       ppsc->pwr_mode = FW_PS_ACTIVE_MODE;
+                       ppsc->smart_ps = 0;
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_LPS_ACTION,
+                                                     (u8 *)(&enter_fwlps));
+                       if (ppsc->p2p_ps_info.opp_ps)
+                               rtl_p2p_ps_cmd(hw,P2P_PS_ENABLE);
+
+               } else {
+                       if (rtl_get_fwlps_doze(hw)) {
+                               RT_TRACE(COMP_RF, DBG_DMESG,
+                                        ("FW LPS enter ps_mode:%x\n",
+                                        ppsc->fwctrl_psmode));
+                               enter_fwlps = true;
+                               ppsc->pwr_mode = ppsc->fwctrl_psmode;
+                               ppsc->smart_ps = 2;
+                               rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                       HW_VAR_FW_LPS_ACTION,
+                                                       (u8 *)(&enter_fwlps));
+
+                       } else {
+                               /* Reset the power save related parameters. */
+                               ppsc->dot11_psmode = EACTIVE;
+                       }
+               }
+       }
+}
+
+/*Enter the leisure power save mode.*/
+void rtl_lps_enter(struct ieee80211_hw *hw)
+{
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       unsigned long flag;
+
+       if (!ppsc->b_fwctrl_lps)
+               return;
+
+       if (rtlpriv->sec.being_setkey)
+               return;
+
+       if (rtlpriv->link_info.b_busytraffic)
+               return;
+
+       /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
+       if (mac->cnt_after_linked < 5)
+               return;
+
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               return;
+
+       if (mac->link_state != MAC80211_LINKED)
+               return;
+
+       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+
+       /* Idle for a while if we connect to AP a while ago. */
+       if (mac->cnt_after_linked >= 2) {
+               if (ppsc->dot11_psmode == EACTIVE) {
+                       RT_TRACE(COMP_POWER, DBG_LOUD,
+                                ("Enter 802.11 power save mode...\n"));
+
+                       rtl_lps_set_psmode(hw, EAUTOPS);
+               }
+       }
+
+       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+}
+
+/*Leave the leisure power save mode.*/
+void rtl_lps_leave(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       unsigned long flag;
+
+       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+
+       if (ppsc->b_fwctrl_lps) {
+               if (ppsc->dot11_psmode != EACTIVE) {
+
+                       /*FIX ME */
+                       rtlpriv->cfg->ops->enable_interrupt(hw);
+
+                       if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
+                           RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
+                           rtlhal->interface == INTF_PCI) {
+                               rtlpriv->intf_ops->disable_aspm(hw);
+                               RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+                       }
+
+                       RT_TRACE(COMP_POWER, DBG_LOUD,
+                                ("Busy Traffic,Leave 802.11 power save..\n"));
+
+                       rtl_lps_set_psmode(hw, EACTIVE);
+               }
+       }
+       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+}
+
+/* For sw LPS*/
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *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;
+       struct ieee80211_tim_ie *tim_ie;
+       u8 *tim;
+       u8 tim_len;
+       bool u_buffed;
+       bool m_buffed;
+
+       if (mac->opmode != NL80211_IFTYPE_STATION)
+               return;
+
+       if (!rtlpriv->psc.b_swctrl_lps)
+               return;
+
+       if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
+               return;
+
+       if (!rtlpriv->psc.sw_ps_enabled)
+               return;
+
+       if (rtlpriv->psc.b_fwctrl_lps)
+               return;
+
+       if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
+               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 (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+               return;
+
+       rtlpriv->psc.last_beacon = jiffies;
+
+       tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
+       if (!tim)
+               return;
+
+       if (tim[1] < sizeof(*tim_ie))
+               return;
+
+       tim_len = tim[1];
+       tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+/*<delete in kernel end>*/
+       if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
+               rtlpriv->psc.dtim_counter = tim_ie->dtim_count;
+/*<delete in kernel start>*/
+#else
+       if (!WARN_ON_ONCE(!mac->vif->bss_conf.dtim_period))
+               rtlpriv->psc.dtim_counter = tim_ie->dtim_count;
+#endif
+/*<delete in kernel end>*/
+
+       /* Check whenever the PHY can be turned off again. */
+
+       /* 1. What about buffered unicast traffic for our AID? */
+       u_buffed = ieee80211_check_tim(tim_ie, tim_len,
+                                      rtlpriv->mac80211.assoc_id);
+
+       /* 2. Maybe the AP wants to send multicast/broadcast data? */
+       m_buffed = tim_ie->bitmap_ctrl & 0x01;
+       rtlpriv->psc.multi_buffered = m_buffed;
+
+       /* unicast will process by mac80211 through
+        * set ~IEEE80211_CONF_PS, So we just check
+        * multicast frames here */
+       if (!m_buffed ) {//&&) {// !rtlpriv->psc.tx_doing) {
+               /* back to low-power land. and delay is
+                * prevent null power save frame tx fail */
+               queue_delayed_work(rtlpriv->works.rtl_wq,
+                                  &rtlpriv->works.ps_work, MSECS(5));
+       } else {
+               RT_TRACE(COMP_POWER, DBG_DMESG,
+                        ("u_bufferd: %x, m_buffered: %x\n",
+                         u_buffed, m_buffed));
+       }
+}
+
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       unsigned long flag;
+
+       if (!rtlpriv->psc.b_swctrl_lps)
+               return;
+       if (mac->link_state != MAC80211_LINKED)
+               return;
+
+       if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
+           RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+               rtlpriv->intf_ops->disable_aspm(hw);
+               RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+       }
+
+       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+       rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false);
+       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+}
+
+void rtl_swlps_rfon_wq_callback(void *data)
+{
+       struct rtl_works *rtlworks =
+           container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq);
+       struct ieee80211_hw *hw = rtlworks->hw;
+
+       rtl_swlps_rf_awake(hw);
+}
+
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       unsigned long flag;
+       u8 sleep_intv;
+
+       if (!rtlpriv->psc.sw_ps_enabled)
+               return;
+
+       if ((rtlpriv->sec.being_setkey) ||
+           (mac->opmode == NL80211_IFTYPE_ADHOC))
+               return;
+
+       /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
+       if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
+               return;
+
+       if (rtlpriv->link_info.b_busytraffic)
+               return;
+
+       spin_lock(&rtlpriv->locks.rf_ps_lock);
+       if (rtlpriv->psc.rfchange_inprogress) {
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
+               return;
+       }
+       spin_unlock(&rtlpriv->locks.rf_ps_lock);
+
+       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+       rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS,false);
+       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+
+       if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+           !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+               rtlpriv->intf_ops->enable_aspm(hw);
+               RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+       }
+
+       /* here is power save alg, when this beacon is DTIM
+        * we will set sleep time to dtim_period * n;
+        * when this beacon is not DTIM, we will set sleep
+        * time to sleep_intv = rtlpriv->psc.dtim_counter or
+        * MAX_SW_LPS_SLEEP_INTV(default set to 5) */
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+/*<delete in kernel end>*/
+       if (rtlpriv->psc.dtim_counter == 0) {
+               if (hw->conf.ps_dtim_period == 1)
+                       sleep_intv = hw->conf.ps_dtim_period * 2;
+               else
+                       sleep_intv = hw->conf.ps_dtim_period;
+       } else {
+               sleep_intv = rtlpriv->psc.dtim_counter;
+       }
+/*<delete in kernel start>*/
+#else
+       if (rtlpriv->psc.dtim_counter == 0) {
+               if (mac->vif->bss_conf.dtim_period == 1)
+                       sleep_intv = mac->vif->bss_conf.dtim_period * 2;
+               else
+                       sleep_intv = mac->vif->bss_conf.dtim_period;
+       } else {
+               sleep_intv = rtlpriv->psc.dtim_counter;
+       }
+#endif
+/*<delete in kernel end>*/
+
+       if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
+               sleep_intv = MAX_SW_LPS_SLEEP_INTV;
+
+       /* this print should always be dtim_conter = 0 &
+        * sleep  = dtim_period, that meaons, we should
+        * awake before every dtim */
+       RT_TRACE(COMP_POWER, DBG_DMESG,
+                ("dtim_counter:%x will sleep :%d beacon_intv\n",
+                 rtlpriv->psc.dtim_counter, sleep_intv));
+
+       /* we tested that 40ms is enough for sw & hw sw delay */
+       queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
+                       MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
+}
+
+
+void rtl_swlps_wq_callback(void *data)
+{
+       struct rtl_works *rtlworks =
+               container_of_dwork_rtl(data, struct rtl_works, ps_work);
+       struct ieee80211_hw *hw = rtlworks->hw;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       bool ps = false;
+
+       ps = (hw->conf.flags & IEEE80211_CONF_PS);
+
+       /* we can sleep after ps null send ok */
+       if (rtlpriv->psc.state_inap) {
+               rtl_swlps_rf_sleep(hw);
+
+               if (rtlpriv->psc.state && !ps) {
+                       rtlpriv->psc.sleep_ms =
+                               jiffies_to_msecs(jiffies -
+                                                rtlpriv->psc.last_action);
+               }
+
+               if (ps)
+                       rtlpriv->psc.last_slept = jiffies;
+
+               rtlpriv->psc.last_action = jiffies;
+               rtlpriv->psc.state = ps;
+       }
+}
+
+
+void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, unsigned int len)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct ieee80211_mgmt *mgmt = (void *)data;
+       struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
+       u8 *pos, *end, *ie;
+       u16 noa_len;
+       static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09};
+       u8 noa_num, index,i, noa_index = 0;
+       bool find_p2p_ie = false , find_p2p_ps_ie = false;
+       pos = (u8 *)mgmt->u.beacon.variable;
+       end = data + len;
+       ie = NULL;
+
+       while (pos + 1 < end) {
+
+               if (pos + 2 + pos[1] > end)
+                       return;
+
+               if (pos[0] == 221 && pos[1] > 4) {
+                       if (memcmp(&pos[2], p2p_oui_ie_type, 4) == 0) {
+                               ie = pos + 2+4;
+                               break;
+                       }
+               }
+               pos += 2 + pos[1];
+       }
+
+       if (ie == NULL)
+               return;
+       find_p2p_ie = true;
+       /*to find noa ie*/
+       while (ie + 1 < end) {
+               noa_len = READEF2BYTE(&ie[1]);
+               if (ie + 3 + ie[1] > end)
+                       return;
+
+               if (ie[0] == 12) {
+                       find_p2p_ps_ie = true;
+                       if ( (noa_len - 2) % 13 != 0){
+                               RT_TRACE(COMP_INIT, DBG_LOUD,
+                                        ("P2P notice of absence: "
+                                         "invalid length.%d\n",noa_len));
+                               return;
+                       } else {
+                               noa_num = (noa_len - 2) / 13;
+                       }
+                       noa_index = ie[3];
+                       if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == P2P_PS_NONE
+                           || noa_index != p2pinfo->noa_index) {
+                               RT_TRACE(COMP_FW, DBG_LOUD,
+                                        ("update NOA ie.\n"));
+                               p2pinfo->noa_index = noa_index;
+                               p2pinfo->opp_ps= (ie[4] >> 7);
+                               p2pinfo->ctwindow = ie[4] & 0x7F;
+                               p2pinfo->noa_num = noa_num;
+                               index = 5;
+                               for (i = 0; i< noa_num; i++){
+                                       p2pinfo->noa_count_type[i] =
+                                                       READEF1BYTE(ie+index);
+                                       index += 1;
+                                       p2pinfo->noa_duration[i] =
+                                                       READEF4BYTE(ie+index);
+                                       index += 4;
+                                       p2pinfo->noa_interval[i] =
+                                                       READEF4BYTE(ie+index);
+                                       index += 4;
+                                       p2pinfo->noa_start_time[i] =
+                                                       READEF4BYTE(ie+index);
+                                       index += 4;
+                               }
+
+                               if (p2pinfo->opp_ps == 1) {
+                                       p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
+                                       /* Driver should wait LPS
+                                        * entering CTWindow*/
+                                       if (rtlpriv->psc.b_fw_current_inpsmode){
+                                               rtl_p2p_ps_cmd(hw,
+                                                              P2P_PS_ENABLE);
+                                       }
+                               } else if (p2pinfo->noa_num > 0) {
+                                       p2pinfo->p2p_ps_mode = P2P_PS_NOA;
+                                       rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
+                               } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
+                                       rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+                               }
+                       }
+
+               break;
+               }
+               ie += 3 + noa_len;
+       }
+
+       if (find_p2p_ie == true) {
+               if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) &&
+                   (find_p2p_ps_ie == false))
+                       rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+       }
+}
+
+void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, unsigned int len)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct ieee80211_mgmt *mgmt = (void *)data;
+       struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
+       bool find_p2p_ie = false , find_p2p_ps_ie = false;
+       u8 noa_num, index,i, noa_index = 0;
+       u8 *pos, *end, *ie;
+       u16 noa_len;
+       static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09};
+
+       pos = (u8 *) &mgmt->u.action.category;
+       end = data + len;
+       ie = NULL;
+
+       if (pos[0] == 0x7f ) {
+               if (memcmp(&pos[1], p2p_oui_ie_type, 4) == 0) {
+                       ie = pos + 3+4;
+               }
+       }
+
+       if (ie == NULL)
+               return;
+       find_p2p_ie = true;
+
+       RT_TRACE(COMP_FW, DBG_LOUD, ("action frame find P2P IE.\n"));
+       /*to find noa ie*/
+       while (ie + 1 < end) {
+               noa_len = READEF2BYTE(&ie[1]);
+               if (ie + 3 + ie[1] > end)
+                       return;
+
+               if (ie[0] == 12) {
+                       RT_TRACE(COMP_FW, DBG_LOUD, ("find NOA IE.\n"));
+                       RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, ("noa ie "),
+                                     ie, noa_len);
+                       find_p2p_ps_ie = true;
+                       if ( (noa_len - 2) % 13 != 0){
+                               RT_TRACE(COMP_FW, DBG_LOUD,
+                                        ("P2P notice of absence: "
+                                         "invalid length.%d\n",noa_len));
+                               return;
+                       } else {
+                               noa_num = (noa_len - 2) / 13;
+                       }
+                       noa_index = ie[3];
+                       if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == P2P_PS_NONE
+                           || noa_index != p2pinfo->noa_index) {
+                               p2pinfo->noa_index = noa_index;
+                               p2pinfo->opp_ps= (ie[4] >> 7);
+                               p2pinfo->ctwindow = ie[4] & 0x7F;
+                               p2pinfo->noa_num = noa_num;
+                               index = 5;
+                               for (i = 0; i< noa_num; i++){
+                                       p2pinfo->noa_count_type[i] =
+                                                       READEF1BYTE(ie+index);
+                                       index += 1;
+                                       p2pinfo->noa_duration[i] =
+                                                       READEF4BYTE(ie+index);
+                                       index += 4;
+                                       p2pinfo->noa_interval[i] =
+                                                       READEF4BYTE(ie+index);
+                                       index += 4;
+                                       p2pinfo->noa_start_time[i] =
+                                                       READEF4BYTE(ie+index);
+                                       index += 4;
+                               }
+
+                               if (p2pinfo->opp_ps == 1) {
+                                       p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
+                                       /* Driver should wait LPS
+                                        * entering CTWindow */
+                                       if (rtlpriv->psc.b_fw_current_inpsmode){
+                                               rtl_p2p_ps_cmd(hw,
+                                                              P2P_PS_ENABLE);
+                                       }
+                               } else if (p2pinfo->noa_num > 0) {
+                                       p2pinfo->p2p_ps_mode = P2P_PS_NOA;
+                                       rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
+                               } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
+                                       rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+                               }
+                       }
+
+               break;
+               }
+               ie += 3 + noa_len;
+       }
+
+
+}
+
+
+void rtl_p2p_ps_cmd(struct ieee80211_hw *hw,u8 p2p_ps_state)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
+       struct rtl_p2p_ps_info  *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
+
+       RT_TRACE(COMP_FW, DBG_LOUD, (" p2p state %x\n",p2p_ps_state));
+       switch (p2p_ps_state) {
+               case P2P_PS_DISABLE:
+                       p2pinfo->p2p_ps_state = p2p_ps_state;
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                  HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
+                                                  (u8 *)(&p2p_ps_state));
+
+                       p2pinfo->noa_index = 0;
+                       p2pinfo->ctwindow = 0;
+                       p2pinfo->opp_ps = 0;
+                       p2pinfo->noa_num = 0;
+                       p2pinfo->p2p_ps_mode = P2P_PS_NONE;
+                       if (rtlps->b_fw_current_inpsmode == true) {
+                               if (rtlps->smart_ps == 0) {
+                                       rtlps->smart_ps = 2;
+                                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                   HW_VAR_H2C_FW_PWRMODE,
+                                                   (u8 *)(&rtlps->pwr_mode));
+                               }
+
+                       }
+                       break;
+               case P2P_PS_ENABLE:
+                       if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
+                               p2pinfo->p2p_ps_state = p2p_ps_state;
+
+                               if (p2pinfo->ctwindow > 0) {
+                                       if (rtlps->smart_ps != 0){
+                                               rtlps->smart_ps = 0;
+                                               rtlpriv->cfg->ops->set_hw_reg(
+                                                   hw, HW_VAR_H2C_FW_PWRMODE,
+                                                   (u8 *)(&rtlps->pwr_mode));
+                                       }
+                               }
+                               rtlpriv->cfg->ops->set_hw_reg(hw,
+                                               HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
+                                               (u8 *)(&p2p_ps_state));
+
+                       }
+                       break;
+               case P2P_PS_SCAN:
+               case P2P_PS_SCAN_DONE:
+               case P2P_PS_ALLSTASLEEP:
+                       if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
+                               p2pinfo->p2p_ps_state = p2p_ps_state;
+                               rtlpriv->cfg->ops->set_hw_reg(hw,
+                                               HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
+                                               (u8 *)(&p2p_ps_state));
+                       }
+                       break;
+               default:
+                       break;
+
+       }
+       RT_TRACE(COMP_FW, DBG_LOUD, (" ctwindow %x oppps %x \n",
+                                    p2pinfo->ctwindow,p2pinfo->opp_ps));
+       RT_TRACE(COMP_FW, DBG_LOUD, ("count %x duration %x index %x interval %x"
+                                    " start time %x noa num %x\n",
+                                    p2pinfo->noa_count_type[0],
+                                    p2pinfo->noa_duration[0],
+                                    p2pinfo->noa_index,
+                                    p2pinfo->noa_interval[0],
+                                    p2pinfo->noa_start_time[0],
+                                    p2pinfo->noa_num));
+       RT_TRACE(COMP_FW, DBG_LOUD, ("end\n"));
+}
+
+void rtl_p2p_info(struct ieee80211_hw *hw, void *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;
+
+       if (!mac->p2p)
+               return;
+       if (mac->link_state != MAC80211_LINKED)
+               return;
+       /* min. beacon length + FCS_LEN */
+       if (len <= 40 + FCS_LEN)
+               return;
+
+       /* and only beacons from the associated BSSID, please */
+       if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+               return;
+
+       /* check if this really is a beacon */
+       if (!(ieee80211_is_beacon(hdr->frame_control) ||
+             ieee80211_is_probe_resp(hdr->frame_control) ||
+             ieee80211_is_action(hdr->frame_control)))
+               return;
+
+       if (ieee80211_is_action(hdr->frame_control)) {
+               rtl_p2p_action_ie(hw,data,len - FCS_LEN);
+       } else {
+               rtl_p2p_noa_ie(hw,data,len - FCS_LEN);
+       }
+
+}
diff --git a/drivers/staging/rtl8821ae/ps.h b/drivers/staging/rtl8821ae/ps.h
new file mode 100644 (file)
index 0000000..374ed77
--- /dev/null
@@ -0,0 +1,55 @@
+/******************************************************************************
+ *
+ * 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 __REALTEK_RTL_PCI_PS_H__
+#define __REALTEK_RTL_PCI_PS_H__
+
+#define MAX_SW_LPS_SLEEP_INTV  5
+
+bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
+                        enum rf_pwrstate state_toset, u32 changesource,
+                        bool protect_or_not);
+bool rtl_ps_enable_nic(struct ieee80211_hw *hw);
+bool rtl_ps_disable_nic(struct ieee80211_hw *hw);
+void rtl_ips_nic_off(struct ieee80211_hw *hw);
+void rtl_ips_nic_on(struct ieee80211_hw *hw);
+void rtl_ips_nic_off_wq_callback(void *data);
+void rtl_lps_enter(struct ieee80211_hw *hw);
+void rtl_lps_leave(struct ieee80211_hw *hw);
+
+void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode);
+
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len);
+void rtl_swlps_wq_callback(void *data);
+void rtl_swlps_rfon_wq_callback(void *data);
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw);
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw);
+void rtl_p2p_ps_cmd(struct ieee80211_hw *hw,u8 p2p_ps_state);
+void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len);
+#endif
diff --git a/drivers/staging/rtl8821ae/rc.c b/drivers/staging/rtl8821ae/rc.c
new file mode 100644 (file)
index 0000000..d387f13
--- /dev/null
@@ -0,0 +1,309 @@
+/******************************************************************************
+ *
+ * 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 "wifi.h"
+#include "base.h"
+#include "rc.h"
+
+/*
+ *Finds the highest rate index we can use
+ *if skb is special data like DHCP/EAPOL, we set should
+ *it to lowest rate CCK_1M, otherwise we set rate to
+ *highest rate based on wireless mode used for iwconfig
+ *show Tx rate.
+ */
+static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
+                                 struct ieee80211_sta *sta,
+                                 struct sk_buff *skb, bool not_data)
+{
+       struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_sta_info *sta_entry = NULL;
+       u8 wireless_mode = 0;
+
+       /*
+        *this rate is no use for true rate, firmware
+        *will control rate at all it just used for
+        *1.show in iwconfig in B/G mode
+        *2.in rtl_get_tcb_desc when we check rate is
+        *      1M we will not use FW rate but user rate.
+        */
+       if (rtlmac->opmode == NL80211_IFTYPE_AP ||
+           rtlmac->opmode == NL80211_IFTYPE_ADHOC ||
+           rtlmac->opmode == NL80211_IFTYPE_MESH_POINT) {
+               if (sta) {
+                       sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+                       wireless_mode = sta_entry->wireless_mode;
+               } else {
+                       return 0;
+               }
+       } else {
+               wireless_mode = rtlmac->mode;
+       }
+
+       if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) || not_data) {
+               return 0;
+       } else {
+               if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                       if (wireless_mode == WIRELESS_MODE_B) {
+                               return B_MODE_MAX_RIX;
+                       } else if (wireless_mode == WIRELESS_MODE_G) {
+                               return G_MODE_MAX_RIX;
+                       } else {
+                               if (get_rf_type(rtlphy) != RF_2T2R)
+                                       return N_MODE_MCS7_RIX;
+                               else
+                                       return N_MODE_MCS15_RIX;
+                       }
+               } else {
+                       if (wireless_mode == WIRELESS_MODE_A) {
+                               return A_MODE_MAX_RIX;
+                       } else {
+                               if (get_rf_type(rtlphy) != RF_2T2R)
+                                       return N_MODE_MCS7_RIX;
+                               else
+                                       return N_MODE_MCS15_RIX;
+                       }
+               }
+       }
+}
+
+static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
+                                   struct ieee80211_sta *sta,
+                                   struct ieee80211_tx_rate *rate,
+                                   struct ieee80211_tx_rate_control *txrc,
+                                   u8 tries, char rix, int rtsctsenable,
+                                   bool not_data)
+{
+       struct rtl_mac *mac = rtl_mac(rtlpriv);
+       u8 sgi_20 = 0, sgi_40 = 0;
+
+       if (sta) {
+               sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+               sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+       }
+       rate->count = tries;
+       rate->idx = rix >= 0x00 ? rix : 0x00;
+
+       if (!not_data) {
+               if (txrc->short_preamble)
+                       rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
+               if (mac->opmode == NL80211_IFTYPE_AP ||
+                       mac->opmode == NL80211_IFTYPE_ADHOC) {
+                       if (sta && (sta->ht_cap.cap &
+                                   IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+                               rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+               } else {
+                       if (mac->bw_40)
+                               rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+               }
+               if (sgi_20 || sgi_40)
+                       rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+               if (sta && sta->ht_cap.ht_supported)
+                       rate->flags |= IEEE80211_TX_RC_MCS;
+       }
+}
+
+static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
+                        void *priv_sta,
+                        struct ieee80211_tx_rate_control *txrc)
+{
+       struct rtl_priv *rtlpriv = ppriv;
+       struct sk_buff *skb = txrc->skb;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_rate *rates = tx_info->control.rates;
+       __le16 fc = rtl_get_fc(skb);
+       u8 try_per_rate, i, rix;
+       bool not_data = !ieee80211_is_data(fc);
+
+       if (rate_control_send_low(sta, priv_sta, txrc))
+               return;
+
+       rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
+       try_per_rate = 1;
+       _rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,
+                               try_per_rate, rix, 1, not_data);
+
+       if (!not_data) {
+               for (i = 1; i < 4; i++)
+                       _rtl_rc_rate_set_series(rtlpriv, sta, &rates[i],
+                                               txrc, i, (rix - i), 1,
+                                               not_data);
+       }
+}
+
+static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv,
+                              struct rtl_sta_info *sta_entry, u16 tid)
+{
+       struct rtl_mac *mac = rtl_mac(rtlpriv);
+
+       if (mac->act_scanning)
+               return false;
+
+       if (mac->opmode == NL80211_IFTYPE_STATION &&
+           mac->cnt_after_linked < 3)
+               return false;
+
+       if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP)
+               return true;
+
+       return false;
+}
+
+/*mac80211 Rate Control callbacks*/
+static void rtl_tx_status(void *ppriv,
+                         struct ieee80211_supported_band *sband,
+                         struct ieee80211_sta *sta, void *priv_sta,
+                         struct sk_buff *skb)
+{
+       struct rtl_priv *rtlpriv = ppriv;
+       struct rtl_mac *mac = rtl_mac(rtlpriv);
+       struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+       __le16 fc = rtl_get_fc(skb);
+       struct rtl_sta_info *sta_entry;
+
+       if (!priv_sta || !ieee80211_is_data(fc))
+               return;
+
+       if (rtl_is_special_data(mac->hw, skb, true))
+               return;
+
+       if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
+           is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
+               return;
+
+       if (sta) {
+               /* Check if aggregation has to be enabled for this tid */
+               sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+               if ((sta->ht_cap.ht_supported == true) &&
+                               !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+                       if (ieee80211_is_data_qos(fc)) {
+                               u8 tid = rtl_get_tid(skb);
+                               if (_rtl_tx_aggr_check(rtlpriv, sta_entry,
+                                                      tid)) {
+                                       sta_entry->tids[tid].agg.agg_state =
+                                               RTL_AGG_PROGRESS;
+                                       /*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+                                       /*<delete in kernel end>*/
+                                       ieee80211_start_tx_ba_session(sta, tid,
+                                                                     5000);
+                                       /*<delete in kernel start>*/
+#else
+                                       ieee80211_start_tx_ba_session(sta, tid);
+#endif
+                                       /*<delete in kernel end>*/
+                               }
+                       }
+               }
+       }
+}
+
+static void rtl_rate_init(void *ppriv,
+                         struct ieee80211_supported_band *sband,
+                         struct cfg80211_chan_def *chandef,
+                         struct ieee80211_sta *sta, void *priv_sta)
+{
+}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0))
+static void rtl_rate_update(void *ppriv,
+                           struct ieee80211_supported_band *sband,
+                           struct ieee80211_sta *sta, void *priv_sta,
+                           u32 changed,
+                           enum nl80211_channel_type oper_chan_type)
+{
+}
+#else
+static void rtl_rate_update(void *ppriv,
+                           struct ieee80211_supported_band *sband,
+                           struct cfg80211_chan_def *chandef,
+                           struct ieee80211_sta *sta, void *priv_sta,
+                           u32 changed)
+{
+}
+#endif
+static void *rtl_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       return rtlpriv;
+}
+
+static void rtl_rate_free(void *rtlpriv)
+{
+       return;
+}
+
+static void *rtl_rate_alloc_sta(void *ppriv,
+                               struct ieee80211_sta *sta, gfp_t gfp)
+{
+       struct rtl_priv *rtlpriv = ppriv;
+       struct rtl_rate_priv *rate_priv;
+
+       rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp);
+       if (!rate_priv) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Unable to allocate private rc structure\n"));
+               return NULL;
+       }
+
+       rtlpriv->rate_priv = rate_priv;
+
+       return rate_priv;
+}
+
+static void rtl_rate_free_sta(void *rtlpriv,
+                             struct ieee80211_sta *sta, void *priv_sta)
+{
+       struct rtl_rate_priv *rate_priv = priv_sta;
+       kfree(rate_priv);
+}
+
+static struct rate_control_ops rtl_rate_ops = {
+       .module = NULL,
+       .name = "rtl_rc",
+       .alloc = rtl_rate_alloc,
+       .free = rtl_rate_free,
+       .alloc_sta = rtl_rate_alloc_sta,
+       .free_sta = rtl_rate_free_sta,
+       .rate_init = rtl_rate_init,
+       .rate_update = rtl_rate_update,
+       .tx_status = rtl_tx_status,
+       .get_rate = rtl_get_rate,
+};
+
+int rtl_rate_control_register(void)
+{
+       return ieee80211_rate_control_register(&rtl_rate_ops);
+}
+
+void rtl_rate_control_unregister(void)
+{
+       ieee80211_rate_control_unregister(&rtl_rate_ops);
+}
diff --git a/drivers/staging/rtl8821ae/rc.h b/drivers/staging/rtl8821ae/rc.h
new file mode 100644 (file)
index 0000000..4afa2c2
--- /dev/null
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ * 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_RC_H__
+#define __RTL_RC_H__
+
+#define B_MODE_MAX_RIX 3
+#define G_MODE_MAX_RIX 11
+#define A_MODE_MAX_RIX 7
+
+/* in mac80211 mcs0-mcs15 is idx0-idx15*/
+#define N_MODE_MCS7_RIX 7
+#define N_MODE_MCS15_RIX 15
+
+struct rtl_rate_priv {
+       u8 ht_cap;
+};
+
+int rtl_rate_control_register(void);
+void rtl_rate_control_unregister(void);
+#endif
diff --git a/drivers/staging/rtl8821ae/regd.c b/drivers/staging/rtl8821ae/regd.c
new file mode 100644 (file)
index 0000000..d89f15c
--- /dev/null
@@ -0,0 +1,503 @@
+/******************************************************************************
+ *
+ * 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 "wifi.h"
+#include "regd.h"
+
+static struct country_code_to_enum_rd allCountries[] = {
+       {COUNTRY_CODE_FCC, "US"},
+       {COUNTRY_CODE_IC, "US"},
+       {COUNTRY_CODE_ETSI, "EC"},
+       {COUNTRY_CODE_SPAIN, "EC"},
+       {COUNTRY_CODE_FRANCE, "EC"},
+       {COUNTRY_CODE_MKK, "JP"},
+       {COUNTRY_CODE_MKK1, "JP"},
+       {COUNTRY_CODE_ISRAEL, "EC"},
+       {COUNTRY_CODE_TELEC, "JP"},
+       {COUNTRY_CODE_MIC, "JP"},
+       {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"},
+       {COUNTRY_CODE_WORLD_WIDE_13, "EC"},
+       {COUNTRY_CODE_TELEC_NETGEAR, "EC"},
+};
+
+/*
+ *Only these channels all allow active
+ *scan on all world regulatory domains
+ */
+#define RTL819x_2GHZ_CH01_11   \
+       REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
+
+/*
+ *We enable active scan on these a case
+ *by case basis by regulatory domain
+ */
+#define RTL819x_2GHZ_CH12_13   \
+       REG_RULE(2467-10, 2472+10, 40, 0, 20,\
+       NL80211_RRF_PASSIVE_SCAN)
+
+#define RTL819x_2GHZ_CH14      \
+       REG_RULE(2484-10, 2484+10, 40, 0, 20, \
+       NL80211_RRF_PASSIVE_SCAN | \
+       NL80211_RRF_NO_OFDM)
+
+/* 5G chan 36 - chan 64*/
+#define RTL819x_5GHZ_5150_5350 \
+       REG_RULE(5150-10, 5350+10, 40, 0, 30, \
+       NL80211_RRF_PASSIVE_SCAN | \
+       NL80211_RRF_NO_IBSS)
+
+/* 5G chan 100 - chan 165*/
+#define RTL819x_5GHZ_5470_5850 \
+       REG_RULE(5470-10, 5850+10, 40, 0, 30, \
+       NL80211_RRF_PASSIVE_SCAN | \
+       NL80211_RRF_NO_IBSS)
+
+/* 5G chan 149 - chan 165*/
+#define RTL819x_5GHZ_5725_5850 \
+       REG_RULE(5725-10, 5850+10, 40, 0, 30, \
+       NL80211_RRF_PASSIVE_SCAN | \
+       NL80211_RRF_NO_IBSS)
+
+#define RTL819x_5GHZ_ALL       \
+       RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850
+
+static const struct ieee80211_regdomain rtl_regdom_11 = {
+       .n_reg_rules = 1,
+       .alpha2 = "99",
+       .reg_rules = {
+                     RTL819x_2GHZ_CH01_11,
+                     }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_12_13 = {
+       .n_reg_rules = 2,
+       .alpha2 = "99",
+       .reg_rules = {
+                     RTL819x_2GHZ_CH01_11,
+                         RTL819x_2GHZ_CH12_13,
+                     }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_no_midband = {
+       .n_reg_rules = 3,
+       .alpha2 = "99",
+       .reg_rules = {
+                     RTL819x_2GHZ_CH01_11,
+                         RTL819x_5GHZ_5150_5350,
+                         RTL819x_5GHZ_5725_5850,
+                     }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_60_64 = {
+       .n_reg_rules = 3,
+       .alpha2 = "99",
+       .reg_rules = {
+                     RTL819x_2GHZ_CH01_11,
+                         RTL819x_2GHZ_CH12_13,
+                         RTL819x_5GHZ_5725_5850,
+                     }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_14_60_64 = {
+       .n_reg_rules = 4,
+       .alpha2 = "99",
+       .reg_rules = {
+                     RTL819x_2GHZ_CH01_11,
+                         RTL819x_2GHZ_CH12_13,
+                         RTL819x_2GHZ_CH14,
+                         RTL819x_5GHZ_5725_5850,
+                     }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_14 = {
+       .n_reg_rules = 3,
+       .alpha2 = "99",
+       .reg_rules = {
+                     RTL819x_2GHZ_CH01_11,
+                         RTL819x_2GHZ_CH12_13,
+                         RTL819x_2GHZ_CH14,
+                     }
+};
+
+static bool _rtl_is_radar_freq(u16 center_freq)
+{
+       return (center_freq >= 5260 && center_freq <= 5700);
+}
+
+static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
+                                          enum nl80211_reg_initiator initiator)
+{
+       enum ieee80211_band band;
+       struct ieee80211_supported_band *sband;
+       const struct ieee80211_reg_rule *reg_rule;
+       struct ieee80211_channel *ch;
+       unsigned int i;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
+       u32 bandwidth = 0;
+       int r;
+#endif
+
+       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+
+               if (!wiphy->bands[band])
+                       continue;
+
+               sband = wiphy->bands[band];
+
+               for (i = 0; i < sband->n_channels; i++) {
+                       ch = &sband->channels[i];
+                       if (_rtl_is_radar_freq(ch->center_freq) ||
+                           (ch->flags & IEEE80211_CHAN_RADAR))
+                               continue;
+                       if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+                               reg_rule = freq_reg_info(wiphy, ch->center_freq);
+                               if (IS_ERR(reg_rule))
+                                       continue;
+#else
+                               r = freq_reg_info(wiphy, ch->center_freq,
+                                                 bandwidth, &reg_rule);
+                               if (r)
+                                       continue;
+#endif
+
+                               /*
+                                *If 11d had a rule for this channel ensure
+                                *we enable adhoc/beaconing if it allows us to
+                                *use it. Note that we would have disabled it
+                                *by applying our static world regdomain by
+                                *default during init, prior to calling our
+                                *regulatory_hint().
+                                */
+
+                               if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
+                                       ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
+                               if (!(reg_rule->flags &
+                                     NL80211_RRF_PASSIVE_SCAN))
+                                       ch->flags &=
+                                           ~IEEE80211_CHAN_PASSIVE_SCAN;
+                       } else {
+                               if (ch->beacon_found)
+                                       ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+                                                  IEEE80211_CHAN_PASSIVE_SCAN);
+                       }
+               }
+       }
+}
+
+/* Allows active scan scan on Ch 12 and 13 */
+static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
+                                            enum nl80211_reg_initiator
+                                            initiator)
+{
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_channel *ch;
+       const struct ieee80211_reg_rule *reg_rule;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
+       u32 bandwidth = 0;
+       int r;
+#endif
+
+       if (!wiphy->bands[IEEE80211_BAND_2GHZ])
+               return;
+       sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+
+       /*
+        *If no country IE has been received always enable active scan
+        *on these channels. This is only done for specific regulatory SKUs
+        */
+       if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+               ch = &sband->channels[11];      /* CH 12 */
+               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+               ch = &sband->channels[12];      /* CH 13 */
+               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+               return;
+       }
+
+       /*
+        *If a country IE has been recieved check its rule for this
+        *channel first before enabling active scan. The passive scan
+        *would have been enforced by the initial processing of our
+        *custom regulatory domain.
+        */
+
+       ch = &sband->channels[11];      /* CH 12 */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+       reg_rule = freq_reg_info(wiphy, ch->center_freq);
+       if (!IS_ERR(reg_rule)) {
+#else
+       r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
+       if (!r) {
+#endif
+               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+       }
+
+       ch = &sband->channels[12];      /* CH 13 */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+       reg_rule = freq_reg_info(wiphy, ch->center_freq);
+       if (!IS_ERR(reg_rule)) {
+#else
+       r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
+       if (!r) {
+#endif
+               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+       }
+}
+
+/*
+ *Always apply Radar/DFS rules on
+ *freq range 5260 MHz - 5700 MHz
+ */
+static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
+{
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_channel *ch;
+       unsigned int i;
+
+       if (!wiphy->bands[IEEE80211_BAND_5GHZ])
+               return;
+
+       sband = wiphy->bands[IEEE80211_BAND_5GHZ];
+
+       for (i = 0; i < sband->n_channels; i++) {
+               ch = &sband->channels[i];
+               if (!_rtl_is_radar_freq(ch->center_freq))
+                       continue;
+
+               /*
+                *We always enable radar detection/DFS on this
+                *frequency range. Additionally we also apply on
+                *this frequency range:
+                *- If STA mode does not yet have DFS supports disable
+                * active scanning
+                *- If adhoc mode does not support DFS yet then disable
+                * adhoc in the frequency.
+                *- If AP mode does not yet support radar detection/DFS
+                *do not allow AP mode
+                */
+               if (!(ch->flags & IEEE80211_CHAN_DISABLED))
+                       ch->flags |= IEEE80211_CHAN_RADAR |
+                           IEEE80211_CHAN_NO_IBSS |
+                           IEEE80211_CHAN_PASSIVE_SCAN;
+       }
+}
+
+static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
+                                      enum nl80211_reg_initiator initiator,
+                                      struct rtl_regulatory *reg)
+{
+       _rtl_reg_apply_beaconing_flags(wiphy, initiator);
+       _rtl_reg_apply_active_scan_flags(wiphy, initiator);
+       return;
+}
+
+static void _rtl_dump_channel_map(struct wiphy *wiphy)
+{
+       enum ieee80211_band band;
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_channel *ch;
+       unsigned int i;
+
+       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+               if (!wiphy->bands[band])
+                       continue;
+               sband = wiphy->bands[band];
+               for (i = 0; i < sband->n_channels; i++)
+                       ch = &sband->channels[i];
+       }
+}
+
+static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
+                                  struct regulatory_request *request,
+                                  struct rtl_regulatory *reg)
+{
+       /* We always apply this */
+       _rtl_reg_apply_radar_flags(wiphy);
+
+       switch (request->initiator) {
+       case NL80211_REGDOM_SET_BY_DRIVER:
+       case NL80211_REGDOM_SET_BY_CORE:
+       case NL80211_REGDOM_SET_BY_USER:
+               break;
+       case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+               _rtl_reg_apply_world_flags(wiphy, request->initiator, reg);
+               break;
+       }
+
+       _rtl_dump_channel_map(wiphy);
+
+       return 0;
+}
+
+static const struct ieee80211_regdomain *_rtl_regdomain_select(
+                                               struct rtl_regulatory *reg)
+{
+       switch (reg->country_code) {
+       case COUNTRY_CODE_FCC:
+               return &rtl_regdom_no_midband;
+       case COUNTRY_CODE_IC:
+               return &rtl_regdom_11;
+       case COUNTRY_CODE_ETSI:
+       case COUNTRY_CODE_TELEC_NETGEAR:
+               return &rtl_regdom_60_64;
+       case COUNTRY_CODE_SPAIN:
+       case COUNTRY_CODE_FRANCE:
+       case COUNTRY_CODE_ISRAEL:
+       case COUNTRY_CODE_WORLD_WIDE_13:
+               return &rtl_regdom_12_13;
+       case COUNTRY_CODE_MKK:
+       case COUNTRY_CODE_MKK1:
+       case COUNTRY_CODE_TELEC:
+       case COUNTRY_CODE_MIC:
+               return &rtl_regdom_14_60_64;
+       case COUNTRY_CODE_GLOBAL_DOMAIN:
+               return &rtl_regdom_14;
+       default:
+               return &rtl_regdom_no_midband;
+       }
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
+                               struct wiphy *wiphy,
+                               void (*reg_notifier) (struct wiphy * wiphy,
+                                                    struct regulatory_request *
+                                                    request))
+#else
+static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
+                               struct wiphy *wiphy,
+                               int (*reg_notifier) (struct wiphy * wiphy,
+                                                    struct regulatory_request *
+                                                    request))
+#endif
+{
+       const struct ieee80211_regdomain *regd;
+
+       wiphy->reg_notifier = reg_notifier;
+
+       wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+       wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
+       wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
+
+       regd = _rtl_regdomain_select(reg);
+       wiphy_apply_custom_regulatory(wiphy, regd);
+       _rtl_reg_apply_radar_flags(wiphy);
+       _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
+       return 0;
+}
+
+static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+               if (allCountries[i].countrycode == countrycode)
+                       return &allCountries[i];
+       }
+       return NULL;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+int rtl_regd_init(struct ieee80211_hw *hw,
+                 void (*reg_notifier) (struct wiphy *wiphy,
+                                       struct regulatory_request *request))
+#else
+int rtl_regd_init(struct ieee80211_hw *hw,
+                 int (*reg_notifier) (struct wiphy *wiphy,
+                                      struct regulatory_request *request))
+#endif
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct wiphy *wiphy = hw->wiphy;
+       struct country_code_to_enum_rd *country = NULL;
+
+       if (wiphy == NULL || &rtlpriv->regd == NULL)
+               return -EINVAL;
+
+       /* init country_code from efuse channel plan */
+       rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan;
+
+       RT_TRACE(COMP_REGD, DBG_TRACE,
+                (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
+                 rtlpriv->regd.country_code));
+
+       if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {
+               RT_TRACE(COMP_REGD, DBG_DMESG,
+                        (KERN_DEBUG "rtl: EEPROM indicates invalid contry code"
+                         "world wide 13 should be used\n"));
+
+               rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
+       }
+
+       country = _rtl_regd_find_country(rtlpriv->regd.country_code);
+
+       if (country) {
+               rtlpriv->regd.alpha2[0] = country->iso_name[0];
+               rtlpriv->regd.alpha2[1] = country->iso_name[1];
+       } else {
+               rtlpriv->regd.alpha2[0] = '0';
+               rtlpriv->regd.alpha2[1] = '0';
+       }
+
+       RT_TRACE(COMP_REGD, DBG_TRACE,
+                (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n",
+                 rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]));
+
+       _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier);
+
+       return 0;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_REGD, DBG_LOUD, ("\n"));
+
+       _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
+}
+#else
+int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_REGD, DBG_LOUD, ("\n"));
+
+       return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
+}
+#endif
diff --git a/drivers/staging/rtl8821ae/regd.h b/drivers/staging/rtl8821ae/regd.h
new file mode 100644 (file)
index 0000000..c126cf9
--- /dev/null
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *
+ * 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_REGD_H__
+#define __RTL_REGD_H__
+
+struct country_code_to_enum_rd {
+       u16 countrycode;
+       const char *iso_name;
+};
+
+enum country_code_type_t {
+       COUNTRY_CODE_FCC = 0,
+       COUNTRY_CODE_IC = 1,
+       COUNTRY_CODE_ETSI = 2,
+       COUNTRY_CODE_SPAIN = 3,
+       COUNTRY_CODE_FRANCE = 4,
+       COUNTRY_CODE_MKK = 5,
+       COUNTRY_CODE_MKK1 = 6,
+       COUNTRY_CODE_ISRAEL = 7,
+       COUNTRY_CODE_TELEC = 8,
+       COUNTRY_CODE_MIC = 9,
+       COUNTRY_CODE_GLOBAL_DOMAIN = 10,
+       COUNTRY_CODE_WORLD_WIDE_13 = 11,
+       COUNTRY_CODE_TELEC_NETGEAR = 12,
+
+       /*add new channel plan above this line */
+       COUNTRY_CODE_MAX
+};
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+int rtl_regd_init(struct ieee80211_hw *hw,
+                 void (*reg_notifier) (struct wiphy *wiphy,
+                                       struct regulatory_request *request));
+void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+#else
+int rtl_regd_init(struct ieee80211_hw *hw,
+                 int (*reg_notifier) (struct wiphy *wiphy,
+                                      struct regulatory_request *request));
+int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+#endif
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/btc.h b/drivers/staging/rtl8821ae/rtl8821ae/btc.h
new file mode 100644 (file)
index 0000000..74ac189
--- /dev/null
@@ -0,0 +1,87 @@
+
+/******************************************************************************
+ **
+ ** 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 __RTL8821AE_BTC_H__
+#define __RTL8821AE_BTC_H__
+
+#include "../wifi.h"
+#include "hal_bt_coexist.h"
+
+struct bt_coexist_c2h_info {
+       u8 no_parse_c2h;
+       u8 has_c2h;
+};
+
+struct btdm_8821ae {
+       bool b_all_off;
+       bool b_agc_table_en;
+       bool b_adc_back_off_on;
+       bool b2_ant_hid_en;
+       bool b_low_penalty_rate_adaptive;
+       bool b_rf_rx_lpf_shrink;
+       bool b_reject_aggre_pkt;
+       bool b_tra_tdma_on;
+       u8 tra_tdma_nav;
+       u8 tra_tdma_ant;
+       bool b_tdma_on;
+       u8 tdma_ant;
+       u8 tdma_nav;
+       u8 tdma_dac_swing;
+       u8 fw_dac_swing_lvl;
+       bool b_ps_tdma_on;
+       u8 ps_tdma_byte[5];
+       bool b_pta_on;
+       u32 val_0x6c0;
+       u32 val_0x6c8;
+       u32 val_0x6cc;
+       bool b_sw_dac_swing_on;
+       u32 sw_dac_swing_lvl;
+       u32 wlan_act_hi;
+       u32 wlan_act_lo;
+       u32 bt_retry_index;
+       bool b_dec_bt_pwr;
+       bool b_ignore_wlan_act;
+};
+
+struct bt_coexist_8821ae {
+       u32 high_priority_tx;
+       u32 high_priority_rx;
+       u32 low_priority_tx;
+       u32 low_priority_rx;
+       u8 c2h_bt_info;
+       bool b_c2h_bt_info_req_sent;
+       bool b_c2h_bt_inquiry_page;
+       u32 bt_inq_page_start_time;
+       u8 bt_retry_cnt;
+       u8 c2h_bt_info_original;
+       u8 bt_inquiry_page_cnt;
+       struct btdm_8821ae btdm;
+};
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/def.h b/drivers/staging/rtl8821ae/rtl8821ae/def.h
new file mode 100644 (file)
index 0000000..72ebdea
--- /dev/null
@@ -0,0 +1,442 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_DEF_H__
+#define __RTL8821AE_DEF_H__
+
+/*--------------------------Define -------------------------------------------*/
+/* BIT 7 HT Rate*/
+/*TxHT = 0*/
+#define        MGN_1M                          0x02
+#define        MGN_2M                          0x04
+#define        MGN_5_5M                        0x0b
+#define        MGN_11M                         0x16
+
+#define        MGN_6M                          0x0c
+#define        MGN_9M                          0x12
+#define        MGN_12M                         0x18
+#define        MGN_18M                         0x24
+#define        MGN_24M                         0x30
+#define        MGN_36M                         0x48
+#define        MGN_48M                         0x60
+#define        MGN_54M                         0x6c
+
+// TxHT = 1
+#define        MGN_MCS0                        0x80
+#define        MGN_MCS1                        0x81
+#define        MGN_MCS2                        0x82
+#define        MGN_MCS3                        0x83
+#define        MGN_MCS4                        0x84
+#define        MGN_MCS5                        0x85
+#define        MGN_MCS6                        0x86
+#define        MGN_MCS7                        0x87
+#define        MGN_MCS8                        0x88
+#define        MGN_MCS9                        0x89
+#define        MGN_MCS10                       0x8a
+#define        MGN_MCS11                       0x8b
+#define        MGN_MCS12                       0x8c
+#define        MGN_MCS13                       0x8d
+#define        MGN_MCS14                       0x8e
+#define        MGN_MCS15                       0x8f
+//VHT rate
+#define        MGN_VHT1SS_MCS0         0x90
+#define        MGN_VHT1SS_MCS1         0x91
+#define        MGN_VHT1SS_MCS2         0x92
+#define        MGN_VHT1SS_MCS3         0x93
+#define        MGN_VHT1SS_MCS4         0x94
+#define        MGN_VHT1SS_MCS5         0x95
+#define        MGN_VHT1SS_MCS6         0x96
+#define        MGN_VHT1SS_MCS7         0x97
+#define        MGN_VHT1SS_MCS8         0x98
+#define        MGN_VHT1SS_MCS9         0x99
+#define        MGN_VHT2SS_MCS0         0x9a
+#define        MGN_VHT2SS_MCS1         0x9b
+#define        MGN_VHT2SS_MCS2         0x9c
+#define        MGN_VHT2SS_MCS3         0x9d
+#define        MGN_VHT2SS_MCS4         0x9e
+#define        MGN_VHT2SS_MCS5         0x9f
+#define        MGN_VHT2SS_MCS6         0xa0
+#define        MGN_VHT2SS_MCS7         0xa1
+#define        MGN_VHT2SS_MCS8         0xa2
+#define        MGN_VHT2SS_MCS9         0xa3
+
+#define        MGN_VHT3SS_MCS0         0xa4
+#define        MGN_VHT3SS_MCS1         0xa5
+#define        MGN_VHT3SS_MCS2         0xa6
+#define        MGN_VHT3SS_MCS3         0xa7
+#define        MGN_VHT3SS_MCS4         0xa8
+#define        MGN_VHT3SS_MCS5         0xa9
+#define        MGN_VHT3SS_MCS6         0xaa
+#define        MGN_VHT3SS_MCS7         0xab
+#define        MGN_VHT3SS_MCS8         0xac
+#define        MGN_VHT3SS_MCS9         0xad
+
+#define        MGN_MCS0_SG                     0xc0
+#define        MGN_MCS1_SG                     0xc1
+#define        MGN_MCS2_SG                     0xc2
+#define        MGN_MCS3_SG                     0xc3
+#define        MGN_MCS4_SG                     0xc4
+#define        MGN_MCS5_SG                     0xc5
+#define        MGN_MCS6_SG                     0xc6
+#define        MGN_MCS7_SG                     0xc7
+#define        MGN_MCS8_SG                     0xc8
+#define        MGN_MCS9_SG                     0xc9
+#define        MGN_MCS10_SG            0xca
+#define        MGN_MCS11_SG            0xcb
+#define        MGN_MCS12_SG            0xcc
+#define        MGN_MCS13_SG            0xcd
+#define        MGN_MCS14_SG            0xce
+#define        MGN_MCS15_SG            0xcf
+
+#define        MGN_UNKNOWN                     0xff
+
+
+/* 30 ms */
+#define        WIFI_NAV_UPPER_US                               30000
+#define HAL_92C_NAV_UPPER_UNIT                 128
+
+#define HAL_RETRY_LIMIT_INFRA                          48
+#define HAL_RETRY_LIMIT_AP_ADHOC                       7
+
+#define RESET_DELAY_8185                                       20
+
+#define RT_IBSS_INT_MASKS      (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
+#define RT_AC_INT_MASKS                (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
+
+#define NUM_OF_FIRMWARE_QUEUE                          10
+#define NUM_OF_PAGES_IN_FW                                     0x100
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK                     0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE                     0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI                     0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO                     0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA           0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_CMD                    0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT           0x02
+#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH           0x02
+#define NUM_OF_PAGE_IN_FW_QUEUE_BCN                    0x2
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB                    0xA1
+
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM         0x026
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM         0x048
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM         0x048
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM         0x026
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM                0x00
+
+#define MAX_RX_DMA_BUFFER_SIZE                         0x3E80
+
+
+#define MAX_LINES_HWCONFIG_TXT                         1000
+#define MAX_BYTES_LINE_HWCONFIG_TXT                    256
+
+#define SW_THREE_WIRE                                          0
+#define HW_THREE_WIRE                                          2
+
+#define BT_DEMO_BOARD                                          0
+#define BT_QA_BOARD                                                    1
+#define BT_FPGA                                                                2
+
+#define HAL_PRIME_CHNL_OFFSET_DONT_CARE                0
+#define HAL_PRIME_CHNL_OFFSET_LOWER                    1
+#define HAL_PRIME_CHNL_OFFSET_UPPER                    2
+
+#define MAX_H2C_QUEUE_NUM                                      10
+
+#define RX_MPDU_QUEUE                                          0
+#define RX_CMD_QUEUE                                           1
+#define RX_MAX_QUEUE                                           2
+#define AC2QUEUEID(_AC)                                                (_AC)
+
+#define        C2H_RX_CMD_HDR_LEN                                      8
+#define        GET_C2H_CMD_CMD_LEN(__prxhdr)           \
+       LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
+#define        GET_C2H_CMD_ELEMENT_ID(__prxhdr)        \
+       LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
+#define        GET_C2H_CMD_CMD_SEQ(__prxhdr)           \
+       LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
+#define        GET_C2H_CMD_CONTINUE(__prxhdr)          \
+       LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
+#define        GET_C2H_CMD_CONTENT(__prxhdr)           \
+       ((u8*)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
+
+#define        GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr)    \
+       LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
+#define        GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr)               \
+       LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
+#define        GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr)   \
+       LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
+#define        GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr)    \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
+#define        GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr)             \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
+#define        GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
+#define        GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr)               \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
+#define        GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr)              \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
+#define        GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr)               \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
+
+#define CHIP_BONDING_IDENTIFIER(_value)        (((_value)>>22)&0x3)
+
+#define CHIP_8812                              BIT(2)
+#define CHIP_8821                              (BIT(0)|BIT(2))
+
+#define CHIP_8821A                                             (BIT(0)|BIT(2))
+#define NORMAL_CHIP                                    BIT(3)
+#define RF_TYPE_1T1R                                   (~(BIT(4)|BIT(5)|BIT(6)))
+#define RF_TYPE_1T2R                                   BIT(4)
+#define RF_TYPE_2T2R                                   BIT(5)
+#define CHIP_VENDOR_UMC                                        BIT(7)
+#define B_CUT_VERSION                                  BIT(12)
+#define C_CUT_VERSION                                  BIT(13)
+#define D_CUT_VERSION                                  ((BIT(12)|BIT(13)))
+#define E_CUT_VERSION                                  BIT(14)
+#define        RF_RL_ID                                                (BIT(31)|BIT(30)|BIT(29)|BIT(28))
+
+
+
+enum version_8821ae {
+       VERSION_TEST_CHIP_1T1R_8812 = 0x0004,
+       VERSION_TEST_CHIP_2T2R_8812 = 0x0024,
+       VERSION_NORMAL_TSMC_CHIP_1T1R_8812 = 0x100c,
+       VERSION_NORMAL_TSMC_CHIP_2T2R_8812 = 0x102c,
+       VERSION_NORMAL_TSMC_CHIP_1T1R_8812_C_CUT = 0x200c,
+       VERSION_NORMAL_TSMC_CHIP_2T2R_8812_C_CUT = 0x202c,
+       VERSION_TEST_CHIP_8821 = 0x0005,
+       VERSION_NORMAL_TSMC_CHIP_8821 = 0x000d,
+       VERSION_NORMAL_TSMC_CHIP_8821_B_CUT = 0x100d,
+       VERSION_UNKNOWN = 0xFF,
+};
+
+enum vht_data_sc{
+       VHT_DATA_SC_DONOT_CARE = 0,
+       VHT_DATA_SC_20_UPPER_OF_80MHZ = 1,
+       VHT_DATA_SC_20_LOWER_OF_80MHZ = 2,
+       VHT_DATA_SC_20_UPPERST_OF_80MHZ = 3,
+       VHT_DATA_SC_20_LOWEST_OF_80MHZ = 4,
+       VHT_DATA_SC_20_RECV1 = 5,
+       VHT_DATA_SC_20_RECV2 = 6,
+       VHT_DATA_SC_20_RECV3 = 7,
+       VHT_DATA_SC_20_RECV4 = 8,
+       VHT_DATA_SC_40_UPPER_OF_80MHZ = 9,
+       VHT_DATA_SC_40_LOWER_OF_80MHZ = 10,
+};
+
+
+/* MASK */
+#define IC_TYPE_MASK                                   (BIT(0)|BIT(1)|BIT(2))
+#define CHIP_TYPE_MASK                                         BIT(3)
+#define RF_TYPE_MASK                                   (BIT(4)|BIT(5)|BIT(6))
+#define MANUFACTUER_MASK                               BIT(7)
+#define ROM_VERSION_MASK                               (BIT(11)|BIT(10)|BIT(9)|BIT(8))
+#define CUT_VERSION_MASK                               (BIT(15)|BIT(14)|BIT(13)|BIT(12))
+
+/* Get element */
+#define GET_CVID_IC_TYPE(version)                      ((version) & IC_TYPE_MASK)
+#define GET_CVID_CHIP_TYPE(version)                    ((version) & CHIP_TYPE_MASK)
+#define GET_CVID_RF_TYPE(version)                      ((version) & RF_TYPE_MASK)
+#define GET_CVID_MANUFACTUER(version)          ((version) & MANUFACTUER_MASK)
+#define GET_CVID_ROM_VERSION(version)          ((version) & ROM_VERSION_MASK)
+#define GET_CVID_CUT_VERSION(version)          ((version) & CUT_VERSION_MASK)
+
+#define IS_1T1R(version)                       ((GET_CVID_RF_TYPE(version))? false : true)
+#define IS_1T2R(version)                       ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)\
+                                                                       ? true : false)
+#define IS_2T2R(version)                       ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)\
+                                                                       ? true : false)
+
+#define IS_8812_SERIES(version)                        ((GET_CVID_IC_TYPE(version) == CHIP_8812)? \
+                                                                               true : false)
+#define IS_8821_SERIES(version)                        ((GET_CVID_IC_TYPE(version) == CHIP_8821)? \
+                                                                               true : false)
+
+#define IS_VENDOR_8812A_TEST_CHIP(version)     ((IS_8812_SERIES(version)) ? \
+                                                                                               ((IS_NORMAL_CHIP(version)) ? \
+                                                                                               false : true) : false)
+#define IS_VENDOR_8812A_MP_CHIP(version)               ((IS_8812_SERIES(version)) ? \
+                                                                                               ((IS_NORMAL_CHIP(version)) ? \
+                                                                                               true : false) : false)
+#define IS_VENDOR_8812A_C_CUT(version)         ((IS_8812_SERIES(version)) ? \
+                                                                                       ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? \
+                                                                                       true : false) : false)
+
+#define IS_VENDOR_8821A_TEST_CHIP(version)     ((IS_8821_SERIES(version)) ? \
+                                                                                               ((IS_NORMAL_CHIP(version)) ? \
+                                                                                               false : true) : false)
+#define IS_VENDOR_8821A_MP_CHIP(version)               ((IS_8821_SERIES(version)) ? \
+                                                                                               ((IS_NORMAL_CHIP(version)) ? \
+                                                                                               true : false) : false)
+#define IS_VENDOR_8821A_B_CUT(version)         ((IS_8821_SERIES(version)) ? \
+                                                                                               ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? \
+                                                                                               true : false) : false)
+
+
+enum rf_optype {
+       RF_OP_BY_SW_3WIRE = 0,
+       RF_OP_BY_FW,
+       RF_OP_MAX
+};
+
+enum rf_power_state {
+       RF_ON,
+       RF_OFF,
+       RF_SLEEP,
+       RF_SHUT_DOWN,
+};
+
+enum power_save_mode {
+       POWER_SAVE_MODE_ACTIVE,
+       POWER_SAVE_MODE_SAVE,
+};
+
+enum power_polocy_config {
+       POWERCFG_MAX_POWER_SAVINGS,
+       POWERCFG_GLOBAL_POWER_SAVINGS,
+       POWERCFG_LOCAL_POWER_SAVINGS,
+       POWERCFG_LENOVO,
+};
+
+enum interface_select_pci {
+       INTF_SEL1_MINICARD = 0,
+       INTF_SEL0_PCIE = 1,
+       INTF_SEL2_RSV = 2,
+       INTF_SEL3_RSV = 3,
+};
+
+enum hal_fw_c2h_cmd_id {
+       HAL_FW_C2H_CMD_Read_MACREG = 0,
+       HAL_FW_C2H_CMD_Read_BBREG = 1,
+       HAL_FW_C2H_CMD_Read_RFREG = 2,
+       HAL_FW_C2H_CMD_Read_EEPROM = 3,
+       HAL_FW_C2H_CMD_Read_EFUSE = 4,
+       HAL_FW_C2H_CMD_Read_CAM = 5,
+       HAL_FW_C2H_CMD_Get_BasicRate = 6,
+       HAL_FW_C2H_CMD_Get_DataRate = 7,
+       HAL_FW_C2H_CMD_Survey = 8,
+       HAL_FW_C2H_CMD_SurveyDone = 9,
+       HAL_FW_C2H_CMD_JoinBss = 10,
+       HAL_FW_C2H_CMD_AddSTA = 11,
+       HAL_FW_C2H_CMD_DelSTA = 12,
+       HAL_FW_C2H_CMD_AtimDone = 13,
+       HAL_FW_C2H_CMD_TX_Report = 14,
+       HAL_FW_C2H_CMD_CCX_Report = 15,
+       HAL_FW_C2H_CMD_DTM_Report = 16,
+       HAL_FW_C2H_CMD_TX_Rate_Statistics = 17,
+       HAL_FW_C2H_CMD_C2HLBK = 18,
+       HAL_FW_C2H_CMD_C2HDBG = 19,
+       HAL_FW_C2H_CMD_C2HFEEDBACK = 20,
+       HAL_FW_C2H_CMD_MAX
+};
+
+enum rtl_desc_qsel {
+       QSLT_BK = 0x2,
+       QSLT_BE = 0x0,
+       QSLT_VI = 0x5,
+       QSLT_VO = 0x7,
+       QSLT_BEACON = 0x10,
+       QSLT_HIGH = 0x11,
+       QSLT_MGNT = 0x12,
+       QSLT_CMD = 0x13,
+};
+
+enum rtl_desc8821ae_rate {
+       DESC_RATE1M = 0x00,
+       DESC_RATE2M = 0x01,
+       DESC_RATE5_5M = 0x02,
+       DESC_RATE11M = 0x03,
+
+       DESC_RATE6M = 0x04,
+       DESC_RATE9M = 0x05,
+       DESC_RATE12M = 0x06,
+       DESC_RATE18M = 0x07,
+       DESC_RATE24M = 0x08,
+       DESC_RATE36M = 0x09,
+       DESC_RATE48M = 0x0a,
+       DESC_RATE54M = 0x0b,
+
+       DESC_RATEMCS0 = 0x0c,
+       DESC_RATEMCS1 = 0x0d,
+       DESC_RATEMCS2 = 0x0e,
+       DESC_RATEMCS3 = 0x0f,
+       DESC_RATEMCS4 = 0x10,
+       DESC_RATEMCS5 = 0x11,
+       DESC_RATEMCS6 = 0x12,
+       DESC_RATEMCS7 = 0x13,
+       DESC_RATEMCS8 = 0x14,
+       DESC_RATEMCS9 = 0x15,
+       DESC_RATEMCS10 = 0x16,
+       DESC_RATEMCS11 = 0x17,
+       DESC_RATEMCS12 = 0x18,
+       DESC_RATEMCS13 = 0x19,
+       DESC_RATEMCS14 = 0x1a,
+       DESC_RATEMCS15 = 0x1b,
+       DESC_RATEVHT1SS_MCS0 = 0x1c,
+       DESC_RATEVHT1SS_MCS1 = 0x1d,
+       DESC_RATEVHT1SS_MCS2 = 0x1e,
+       DESC_RATEVHT1SS_MCS3 = 0x1f,
+       DESC_RATEVHT1SS_MCS4 = 0x20,
+       DESC_RATEVHT1SS_MCS5 = 0x21,
+       DESC_RATEVHT1SS_MCS6 = 0x22,
+       DESC_RATEVHT1SS_MCS7 = 0x23,
+       DESC_RATEVHT1SS_MCS8 = 0x24,
+       DESC_RATEVHT1SS_MCS9 = 0x25,
+       DESC_RATEVHT2SS_MCS0 = 0x26,
+       DESC_RATEVHT2SS_MCS1 = 0x27,
+       DESC_RATEVHT2SS_MCS2 = 0x28,
+       DESC_RATEVHT2SS_MCS3 = 0x29,
+       DESC_RATEVHT2SS_MCS4 = 0x2a,
+       DESC_RATEVHT2SS_MCS5 = 0x2b,
+       DESC_RATEVHT2SS_MCS6 = 0x2c,
+       DESC_RATEVHT2SS_MCS7 = 0x2d,
+       DESC_RATEVHT2SS_MCS8 = 0x2e,
+       DESC_RATEVHT2SS_MCS9 = 0x2f,
+};
+
+enum rx_packet_type{
+       NORMAL_RX,
+       TX_REPORT1,
+       TX_REPORT2,
+       HIS_REPORT,
+       C2H_PACKET,
+};
+
+struct phy_sts_cck_8821ae_t {
+       u8 adc_pwdb_X[4];
+       u8 sq_rpt;
+       u8 cck_agc_rpt;
+};
+
+struct h2c_cmd_8821ae {
+       u8 element_id;
+       u32 cmd_len;
+       u8 *p_cmdbuffer;
+};
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/dm.c b/drivers/staging/rtl8821ae/rtl8821ae/dm.c
new file mode 100644 (file)
index 0000000..41bd21d
--- /dev/null
@@ -0,0 +1,3045 @@
+/******************************************************************************
+ *
+ * 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 "../wifi.h"
+#include "../base.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "trx.h"
+#include "../btcoexist/rtl_btc.h"
+
+struct dig_t dm_digtable;
+static struct ps_t dm_pstable;
+
+static const u32 rtl8812ae_txscaling_table[TXSCALE_TABLE_SIZE] =
+{
+       0x081, // 0,  -12.0dB
+       0x088, // 1,  -11.5dB
+       0x090, // 2,  -11.0dB
+       0x099, // 3,  -10.5dB
+       0x0A2, // 4,  -10.0dB
+       0x0AC, // 5,  -9.5dB
+       0x0B6, // 6,  -9.0dB
+       0x0C0, // 7,  -8.5dB
+       0x0CC, // 8,  -8.0dB
+       0x0D8, // 9,  -7.5dB
+       0x0E5, // 10, -7.0dB
+       0x0F2, // 11, -6.5dB
+       0x101, // 12, -6.0dB
+       0x110, // 13, -5.5dB
+       0x120, // 14, -5.0dB
+       0x131, // 15, -4.5dB
+       0x143, // 16, -4.0dB
+       0x156, // 17, -3.5dB
+       0x16A, // 18, -3.0dB
+       0x180, // 19, -2.5dB
+       0x197, // 20, -2.0dB
+       0x1AF, // 21, -1.5dB
+       0x1C8, // 22, -1.0dB
+       0x1E3, // 23, -0.5dB
+       0x200, // 24, +0  dB
+       0x21E, // 25, +0.5dB
+       0x23E, // 26, +1.0dB
+       0x261, // 27, +1.5dB
+       0x285, // 28, +2.0dB
+       0x2AB, // 29, +2.5dB
+       0x2D3, // 30, +3.0dB
+       0x2FE, // 31, +3.5dB
+       0x32B, // 32, +4.0dB
+       0x35C, // 33, +4.5dB
+       0x38E, // 34, +5.0dB
+       0x3C4, // 35, +5.5dB
+       0x3FE  // 36, +6.0dB
+};
+
+static const u32 rtl8821ae_txscaling_table[TXSCALE_TABLE_SIZE] = {
+       0x081, // 0,  -12.0dB
+       0x088, // 1,  -11.5dB
+       0x090, // 2,  -11.0dB
+       0x099, // 3,  -10.5dB
+       0x0A2, // 4,  -10.0dB
+       0x0AC, // 5,  -9.5dB
+       0x0B6, // 6,  -9.0dB
+       0x0C0, // 7,  -8.5dB
+       0x0CC, // 8,  -8.0dB
+       0x0D8, // 9,  -7.5dB
+       0x0E5, // 10, -7.0dB
+       0x0F2, // 11, -6.5dB
+       0x101, // 12, -6.0dB
+       0x110, // 13, -5.5dB
+       0x120, // 14, -5.0dB
+       0x131, // 15, -4.5dB
+       0x143, // 16, -4.0dB
+       0x156, // 17, -3.5dB
+       0x16A, // 18, -3.0dB
+       0x180, // 19, -2.5dB
+       0x197, // 20, -2.0dB
+       0x1AF, // 21, -1.5dB
+       0x1C8, // 22, -1.0dB
+       0x1E3, // 23, -0.5dB
+       0x200, // 24, +0  dB
+       0x21E, // 25, +0.5dB
+       0x23E, // 26, +1.0dB
+       0x261, // 27, +1.5dB
+       0x285, // 28, +2.0dB
+       0x2AB, // 29, +2.5dB
+       0x2D3, // 30, +3.0dB
+       0x2FE, // 31, +3.5dB
+       0x32B, // 32, +4.0dB
+       0x35C, // 33, +4.5dB
+       0x38E, // 34, +5.0dB
+       0x3C4, // 35, +5.5dB
+       0x3FE  // 36, +6.0dB
+};
+
+static const u32 ofdmswing_table[] = {
+       0x0b40002d, // 0,  -15.0dB
+       0x0c000030, // 1,  -14.5dB
+       0x0cc00033, // 2,  -14.0dB
+       0x0d800036, // 3,  -13.5dB
+       0x0e400039, // 4,  -13.0dB
+       0x0f00003c, // 5,  -12.5dB
+       0x10000040, // 6,  -12.0dB
+       0x11000044, // 7,  -11.5dB
+       0x12000048, // 8,  -11.0dB
+       0x1300004c, // 9,  -10.5dB
+       0x14400051, // 10, -10.0dB
+       0x15800056, // 11, -9.5dB
+       0x16c0005b, // 12, -9.0dB
+       0x18000060, // 13, -8.5dB
+       0x19800066, // 14, -8.0dB
+       0x1b00006c, // 15, -7.5dB
+       0x1c800072, // 16, -7.0dB
+       0x1e400079, // 17, -6.5dB
+       0x20000080, // 18, -6.0dB
+       0x22000088, // 19, -5.5dB
+       0x24000090, // 20, -5.0dB
+       0x26000098, // 21, -4.5dB
+       0x288000a2, // 22, -4.0dB
+       0x2ac000ab, // 23, -3.5dB
+       0x2d4000b5, // 24, -3.0dB
+       0x300000c0, // 25, -2.5dB
+       0x32c000cb, // 26, -2.0dB
+       0x35c000d7, // 27, -1.5dB
+       0x390000e4, // 28, -1.0dB
+       0x3c8000f2, // 29, -0.5dB
+       0x40000100, // 30, +0dB
+       0x43c0010f, // 31, +0.5dB
+       0x47c0011f, // 32, +1.0dB
+       0x4c000130, // 33, +1.5dB
+       0x50800142, // 34, +2.0dB
+       0x55400155, // 35, +2.5dB
+       0x5a400169, // 36, +3.0dB
+       0x5fc0017f, // 37, +3.5dB
+       0x65400195, // 38, +4.0dB
+       0x6b8001ae, // 39, +4.5dB
+       0x71c001c7, // 40, +5.0dB
+       0x788001e2, // 41, +5.5dB
+       0x7f8001fe  // 42, +6.0dB
+};
+
+static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
+       {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01},       //  0, -16.0dB
+       {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},       //  1, -15.5dB
+       {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},       //  2, -15.0dB
+       {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},       //  3, -14.5dB
+       {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},       //  4, -14.0dB
+       {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},       //  5, -13.5dB
+       {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},       //  6, -13.0dB
+       {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},       //  7, -12.5dB
+       {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},       //  8, -12.0dB
+       {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},       //  9, -11.5dB
+       {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},       // 10, -11.0dB
+       {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},       // 11, -10.5dB
+       {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},       // 12, -10.0dB
+       {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},       // 13, -9.5dB
+       {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},       // 14, -9.0dB
+       {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},       // 15, -8.5dB
+       {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},       // 16, -8.0dB
+       {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},       // 17, -7.5dB
+       {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},       // 18, -7.0dB
+       {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},       // 19, -6.5dB
+    {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},  // 20, -6.0dB
+       {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},       // 21, -5.5dB
+       {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},       // 22, -5.0dB
+       {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},       // 23, -4.5dB
+       {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},       // 24, -4.0dB
+       {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},       // 25, -3.5dB
+       {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},       // 26, -3.0dB
+       {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},       // 27, -2.5dB
+       {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},       // 28, -2.0dB
+       {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},       // 29, -1.5dB
+       {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},       // 30, -1.0dB
+       {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},       // 31, -0.5dB
+       {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}        // 32, +0dB
+};
+
+static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8]= {
+       {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00},       //  0, -16.0dB
+       {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},       //  1, -15.5dB
+       {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},       //  2, -15.0dB
+       {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},       //  3, -14.5dB
+       {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},       //  4, -14.0dB
+       {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},       //  5, -13.5dB
+       {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},       //  6, -13.0dB
+       {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},       //  7, -12.5dB
+       {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},       //  8, -12.0dB
+       {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},       //  9, -11.5dB
+       {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},       // 10, -11.0dB
+       {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},       // 11, -10.5dB
+       {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},       // 12, -10.0dB
+       {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},       // 13, -9.5dB
+       {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},       // 14, -9.0dB
+       {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},       // 15, -8.5dB
+       {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},       // 16, -8.0dB
+       {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},       // 17, -7.5dB
+       {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},       // 18, -7.0dB
+       {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},       // 19, -6.5dB
+       {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},       // 20, -6.0dB
+       {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},       // 21, -5.5dB
+       {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},       // 22, -5.0dB
+       {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},       // 23, -4.5dB
+       {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},       // 24, -4.0dB
+       {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},       // 25, -3.5dB
+       {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},       // 26, -3.0dB
+       {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},       // 27, -2.5dB
+       {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},       // 28, -2.0dB
+       {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},       // 29, -1.5dB
+       {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},       // 30, -1.0dB
+       {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},       // 31, -0.5dB
+       {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}        // 32, +0dB
+};
+
+static const u32 edca_setting_dl[PEER_MAX] = {
+       0xa44f,         /* 0 UNKNOWN */
+       0x5ea44f,       /* 1 REALTEK_90 */
+       0x5e4322,       /* 2 REALTEK_92SE */
+       0x5ea42b,               /* 3 BROAD      */
+       0xa44f,         /* 4 RAL */
+       0xa630,         /* 5 ATH */
+       0x5ea630,               /* 6 CISCO */
+       0x5ea42b,               /* 7 MARVELL */
+};
+
+static const u32 edca_setting_ul[PEER_MAX] = {
+       0x5e4322,       /* 0 UNKNOWN */
+       0xa44f,         /* 1 REALTEK_90 */
+       0x5ea44f,       /* 2 REALTEK_92SE */
+       0x5ea32b,       /* 3 BROAD */
+       0x5ea422,       /* 4 RAL */
+       0x5ea322,       /* 5 ATH */
+       0x3ea430,       /* 6 CISCO */
+       0x5ea44f,       /* 7 MARV */
+};
+
+static u8 rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack[] =
+       {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4,  4,  4,  4,  4,  4,  5,  5,  7,  7,  8,  8,  8,  9,  9,  9,  9,  9};
+static u8 rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack[] =
+       {0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5,  6,  6,  7,  7,  7,  7,  8,  8,  9,  9, 10, 10, 10, 11, 11, 11, 11};
+
+
+u8 rtl8812ae_delta_swing_table_idx_24gb_n_txpwrtrack[]    =
+       {0, 1, 1, 1, 2, 2, 2, 3, 3,  3,  4,  4,  5,  5,  5,  6,  6,  6,  7,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11};
+u8 rtl8812ae_delta_swing_table_idx_24gb_p_txpwrtrack[]    =
+       {0, 0, 1, 1, 2, 2, 2, 2, 3,  3,  3,  4,  4,  5,  5,  6,  6,  6,  7,  7,  7,  8,  8,  8,  9,  9,  9,  9,  9,  9};
+u8 rtl8812ae_delta_swing_table_idx_24ga_n_txpwrtrack[]    =
+       {0, 1, 1, 1, 2, 2, 2, 3, 3,  3,  4,  4,  5,  5,  5,  6,  6,  6,  7,  8,  8,  9,  9,  9, 10, 10, 10, 10, 11, 11};
+u8 rtl8812ae_delta_swing_table_idx_24ga_p_txpwrtrack[]    =
+       {0, 0, 1, 1, 2, 2, 2, 2, 3,  3,  3,  4,  4,  5,  5,  6,  6,  6,  7,  7,  7,  8,  8,  8,  9,  9,  9,  9,  9,  9};
+u8 rtl8812ae_delta_swing_table_idx_24gcckb_n_txpwrtrack[] =
+       {0, 1, 1, 1, 2, 2, 2, 3, 3,  3,  4,  4,  5,  5,  5,  6,  6,  6,  7,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11};
+u8 rtl8812ae_delta_swing_table_idx_24gcckb_p_txpwrtrack[] =
+       {0, 0, 1, 1, 2, 2, 2, 2, 3,  3,  3,  4,  4,  5,  5,  6,  6,  6,  7,  7,  7,  8,  8,  8,  9,  9,  9,  9,  9,  9};
+u8 rtl8812ae_delta_swing_table_idx_24gccka_n_txpwrtrack[] =
+       {0, 1, 1, 1, 2, 2, 2, 3, 3,  3,  4,  4,  5,  5,  5,  6,  6,  6,  7,  8,  8,  9,  9,  9, 10, 10, 10, 10, 11, 11};
+u8 rtl8812ae_delta_swing_table_idx_24gccka_p_txpwrtrack[] =
+       {0, 0, 1, 1, 2, 2, 2, 2, 3,  3,  3,  4,  4,  5,  5,  6,  6,  6,  7,  7,  7,  8,  8,  8,  9,  9,  9,  9,  9,  9};
+
+u8 rtl8812ae_delta_swing_table_idx_5gb_n_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
+       {0, 1, 1, 2, 2, 2, 3, 3, 4,  4,  5,  5,  6,  6,  6,  7,  7,  7,  8,  8,  9,  9,  9, 10, 10, 11, 11, 12, 12, 13},
+       {0, 1, 1, 2, 2, 2, 3, 3, 4,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 13, 13},
+       {0, 1, 1, 2, 3, 3, 4, 4, 5,  6,  6,  7,  8,  9, 10, 11, 12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18},
+};
+u8 rtl8812ae_delta_swing_table_idx_5gb_p_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
+       {0, 1, 1, 2, 2, 3, 3, 4, 4,  5,  5,  6,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
+       {0, 1, 1, 2, 2, 3, 3, 4, 4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
+       {0, 1, 1, 2, 2, 3, 3, 4, 4,  5,  5,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
+};
+u8 rtl8812ae_delta_swing_table_idx_5ga_n_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
+       {0, 1, 1, 2, 2, 3, 3, 4, 4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13},
+       {0, 1, 1, 2, 2, 2, 3, 3, 4,  4,  5,  5,  6,  6,  7,  8,  9,  9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13},
+       {0, 1, 1, 2, 2, 3, 3, 4, 5,  6,  7,  8,  8,  9, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18},
+};
+u8 rtl8812ae_delta_swing_table_idx_5ga_p_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
+       {0, 1, 1, 2, 2, 3, 3, 4, 4,  4,  4,  5,  5,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
+       {0, 1, 1, 2, 2, 3, 3, 4, 4,  4,  5,  5,  6,  6,  7,  7,  8,  9,  9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
+       {0, 1, 1, 2, 3, 3, 4, 4, 5,  6,  6,  7,  7,  8,  9,  9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
+};
+
+u8 rtl8821ae_delta_swing_table_idx_24gb_n_txpwrtrack[] =
+       {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
+u8 rtl8821ae_delta_swing_table_idx_24gb_p_txpwrtrack[]  =
+       {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
+u8 rtl8821ae_delta_swing_table_idx_24ga_n_txpwrtrack[]  =
+       {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
+u8 rtl8821ae_delta_swing_table_idx_24ga_p_txpwrtrack[] =
+       {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
+u8 rtl8821ae_delta_swing_table_idx_24gcckb_n_txpwrtrack[] =
+       {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
+u8 rtl8821ae_delta_swing_table_idx_24gcckb_p_txpwrtrack[] =
+       {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
+u8 rtl8821ae_delta_swing_table_idx_24gccka_n_txpwrtrack[] =
+       {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
+u8 rtl8821ae_delta_swing_table_idx_24gccka_p_txpwrtrack[] =
+       {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
+
+u8 rtl8821ae_delta_swing_table_idx_5gb_n_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+};
+
+u8 rtl8821ae_delta_swing_table_idx_5gb_p_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+};
+
+u8 rtl8821ae_delta_swing_table_idx_5ga_n_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+};
+
+u8 rtl8821ae_delta_swing_table_idx_5ga_p_txpwrtrack[][DELTA_SWINGIDX_SIZE] = {
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+       {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
+};
+
+void rtl8812ae_dm_read_and_config_txpower_track(
+       struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("===> rtl8821ae_dm_read_and_config_txpower_track\n"));
+
+
+       memcpy(rtldm->delta_swing_table_idx_24ga_p,
+               rtl8812ae_delta_swing_table_idx_24ga_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24ga_n,
+               rtl8812ae_delta_swing_table_idx_24ga_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gb_p,
+               rtl8812ae_delta_swing_table_idx_24gb_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gb_n,
+               rtl8812ae_delta_swing_table_idx_24gb_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
+
+       memcpy(rtldm->delta_swing_table_idx_24gccka_p,
+               rtl8812ae_delta_swing_table_idx_24gccka_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gccka_n,
+               rtl8812ae_delta_swing_table_idx_24gccka_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gcckb_p,
+               rtl8812ae_delta_swing_table_idx_24gcckb_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gcckb_n,
+               rtl8812ae_delta_swing_table_idx_24gcckb_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
+
+       memcpy(rtldm->delta_swing_table_idx_5ga_p,
+               rtl8812ae_delta_swing_table_idx_5ga_p_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
+       memcpy(rtldm->delta_swing_table_idx_5ga_n,
+               rtl8812ae_delta_swing_table_idx_5ga_n_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
+       memcpy(rtldm->delta_swing_table_idx_5gb_p,
+               rtl8812ae_delta_swing_table_idx_5gb_p_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
+       memcpy(rtldm->delta_swing_table_idx_5gb_n,
+               rtl8812ae_delta_swing_table_idx_5gb_n_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
+}
+
+void rtl8821ae_dm_read_and_config_txpower_track(
+       struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("===> rtl8821ae_dm_read_and_config_txpower_track\n"));
+
+
+       memcpy(rtldm->delta_swing_table_idx_24ga_p,
+               rtl8821ae_delta_swing_table_idx_24ga_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24ga_n,
+               rtl8821ae_delta_swing_table_idx_24ga_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gb_p,
+               rtl8821ae_delta_swing_table_idx_24gb_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gb_n,
+               rtl8821ae_delta_swing_table_idx_24gb_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
+
+       memcpy(rtldm->delta_swing_table_idx_24gccka_p,
+               rtl8821ae_delta_swing_table_idx_24gccka_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gccka_n,
+               rtl8821ae_delta_swing_table_idx_24gccka_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gcckb_p,
+               rtl8821ae_delta_swing_table_idx_24gcckb_p_txpwrtrack, DELTA_SWINGIDX_SIZE);
+       memcpy(rtldm->delta_swing_table_idx_24gcckb_n,
+               rtl8821ae_delta_swing_table_idx_24gcckb_n_txpwrtrack, DELTA_SWINGIDX_SIZE);
+
+       memcpy(rtldm->delta_swing_table_idx_5ga_p,
+               rtl8821ae_delta_swing_table_idx_5ga_p_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
+       memcpy(rtldm->delta_swing_table_idx_5ga_n,
+               rtl8821ae_delta_swing_table_idx_5ga_n_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
+       memcpy(rtldm->delta_swing_table_idx_5gb_p,
+               rtl8821ae_delta_swing_table_idx_5gb_p_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
+       memcpy(rtldm->delta_swing_table_idx_5gb_n,
+               rtl8821ae_delta_swing_table_idx_5gb_n_txpwrtrack, DELTA_SWINGIDX_SIZE*3);
+}
+
+
+
+#define        CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \
+                                       do {\
+                                               for(_offset = 0; _offset < _size; _offset++)\
+                                               {\
+                                                       if(_deltaThermal < thermal_threshold[_direction][_offset])\
+                                                       {\
+                                                               if(_offset != 0)\
+                                                                       _offset--;\
+                                                               break;\
+                                                       }\
+                                               }                       \
+                                               if(_offset >= _size)\
+                                                       _offset = _size-1;\
+                                       } while(0)
+
+
+void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw,
+                                                                                                  u8 type,u8 *pdirection,
+                                                                                                  u32 *poutwrite_val)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       u8 pwr_val = 0;
+
+       if (type == 0){
+               if (rtlpriv->dm.bb_swing_idx_ofdm[RF90_PATH_A] <=
+                       rtlpriv->dm.bb_swing_idx_ofdm_base[RF90_PATH_A]) {
+                       *pdirection = 1;
+                       pwr_val = rtldm->bb_swing_idx_ofdm_base[RF90_PATH_A] - rtldm->bb_swing_idx_ofdm[RF90_PATH_A];
+               } else {
+                       *pdirection = 2;
+                       pwr_val = rtldm->bb_swing_idx_ofdm[RF90_PATH_A] - rtldm->bb_swing_idx_ofdm_base[RF90_PATH_A];
+               }
+       } else if (type ==1) {
+               if (rtldm->bb_swing_idx_cck <= rtldm->bb_swing_idx_cck_base) {
+                       *pdirection = 1;
+                       pwr_val = rtldm->bb_swing_idx_cck_base - rtldm->bb_swing_idx_cck;
+               } else {
+                       *pdirection = 2;
+                       pwr_val = rtldm->bb_swing_idx_cck - rtldm->bb_swing_idx_cck_base;
+               }
+       }
+
+       if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
+               pwr_val = TXPWRTRACK_MAX_IDX;
+
+       *poutwrite_val = pwr_val |(pwr_val << 8)|(pwr_val << 16) | (pwr_val << 24);
+}
+
+void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm *rtldm = rtl_dm(rtlpriv);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
+       u8 p = 0;
+       rtldm->bb_swing_idx_cck_base = rtldm->default_cck_index;
+       rtldm->bb_swing_idx_cck = rtldm->default_cck_index;
+       rtldm->cck_index = 0;
+
+       for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) {
+               rtldm->bb_swing_idx_ofdm_base[p] = rtldm->default_ofdm_index;
+               rtldm->bb_swing_idx_ofdm[p] = rtldm->default_ofdm_index;
+               rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
+
+               rtldm->power_index_offset[p] = 0;
+               rtldm->delta_power_index[p] = 0;
+               rtldm->delta_power_index_last[p] = 0;
+
+               rtldm->aboslute_ofdm_swing_idx[p] = 0;    /*Initial Mix mode power tracking*/
+               rtldm->remnant_ofdm_swing_idx[p] = 0;
+       }
+
+       rtldm->modify_txagc_flag_path_a = false;       /*Initial at Modify Tx Scaling Mode*/
+       rtldm->modify_txagc_flag_path_b = false;       /*Initial at Modify Tx Scaling Mode*/
+       rtldm->remnant_cck_idx = 0;
+       rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
+       rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
+       rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
+}
+
+u8  rtl8821ae_dm_get_swing_index(struct ieee80211_hw *hw)
+{
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 i = 0;
+       u32  bb_swing;
+
+       bb_swing =rtl8821ae_phy_query_bb_reg(hw, rtlhal->current_bandtype, RF90_PATH_A);
+
+       for (i = 0; i < TXSCALE_TABLE_SIZE; ++i)
+               if ( bb_swing == rtl8821ae_txscaling_table[i])
+                       break;
+
+       return i;
+}
+
+void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(
+                               struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm *rtldm = rtl_dm(rtlpriv);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 default_swing_index  = 0;
+       u8 p = 0;
+
+       rtlpriv->dm.txpower_track_control = true;
+       rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
+       rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
+       rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+               rtl8812ae_dm_read_and_config_txpower_track(hw);
+       else
+               rtl8821ae_dm_read_and_config_txpower_track(hw);
+
+       default_swing_index = rtl8821ae_dm_get_swing_index(hw);
+
+       rtldm->default_ofdm_index = (default_swing_index == TXSCALE_TABLE_SIZE) ? 24 : default_swing_index;
+       rtldm->default_cck_index = 24;
+
+       rtldm->bb_swing_idx_cck_base = rtldm->default_cck_index;
+       rtldm->cck_index = rtldm->default_cck_index;
+
+       for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p)
+       {
+               rtldm->bb_swing_idx_ofdm_base[p] = rtldm->default_ofdm_index;
+               rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
+               rtldm->delta_power_index[p] = 0;
+               rtldm->power_index_offset[p] = 0;
+               rtldm->delta_power_index_last[p] = 0;
+       }
+}
+
+static void rtl8821ae_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
+{
+       dm_pstable.pre_ccastate = CCA_MAX;
+       dm_pstable.cur_ccasate = CCA_MAX;
+       dm_pstable.pre_rfstate = RF_MAX;
+       dm_pstable.cur_rfstate = RF_MAX;
+       dm_pstable.rssi_val_min = 0;
+       dm_pstable.initialize = 0;
+}
+
+
+static void rtl8821ae_dm_diginit(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       //dm_digtable.dig_enable_flag = true;
+       dm_digtable.cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
+       /*dm_digtable.pre_igvalue = 0;
+       dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
+       dm_digtable.presta_connectstate = DIG_STA_DISCONNECT;
+       dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT;*/
+       dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
+       dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
+       dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
+       dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
+       dm_digtable.rx_gain_range_max = DM_DIG_MAX;
+       dm_digtable.rx_gain_range_min = DM_DIG_MIN;
+       dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
+       dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX;
+       dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN;
+       dm_digtable.pre_cck_cca_thres = 0xff;
+       dm_digtable.cur_cck_cca_thres = 0x83;
+       dm_digtable.forbidden_igi = DM_DIG_MIN;
+       dm_digtable.large_fa_hit = 0;
+       dm_digtable.recover_cnt = 0;
+       dm_digtable.dig_dynamic_min_0 = DM_DIG_MIN;
+       dm_digtable.dig_dynamic_min_1 = DM_DIG_MIN;
+       dm_digtable.b_media_connect_0 = false;
+       dm_digtable.b_media_connect_1 = false;
+       rtlpriv->dm.b_dm_initialgain_enable = true;
+       dm_digtable.bt30_cur_igi = 0x32;
+}
+
+static void rtl8821ae_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->dm.bdynamic_txpower_enable = false;
+
+       rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
+       rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+}
+
+
+void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       rtlpriv->dm.bcurrent_turbo_edca = false;
+       rtlpriv->dm.bis_any_nonbepkts = false;
+       rtlpriv->dm.bis_cur_rdlstate = false;
+}
+
+
+void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rate_adaptive *p_ra = &(rtlpriv->ra);
+
+       p_ra->ratr_state = DM_RATR_STA_INIT;
+       p_ra->pre_ratr_state = DM_RATR_STA_INIT;
+
+       rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
+       if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
+               rtlpriv->dm.b_useramask = true;
+       else
+               rtlpriv->dm.b_useramask = false;
+
+       p_ra->high_rssi_thresh_for_ra = 50;
+       p_ra->low_rssi_thresh_for_ra = 20;
+}
+
+
+static void rtl8821ae_dm_init_txpower_tracking(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->dm.btxpower_tracking = true;
+       rtlpriv->dm.btxpower_trackinginit = false;
+       rtlpriv->dm.txpowercount = 0;
+       rtlpriv->dm.txpower_track_control = true;
+       rtlpriv->dm.thermalvalue = 0;
+
+       rtlpriv->dm.ofdm_index[0] = 30;
+       rtlpriv->dm.cck_index = 20;
+
+       rtlpriv->dm.bb_swing_idx_cck_base = rtlpriv->dm.cck_index;
+
+
+       rtlpriv->dm.bb_swing_idx_ofdm[RF90_PATH_A] = rtlpriv->dm.ofdm_index[0];
+       rtlpriv->dm.bb_swing_idx_ofdm[RF90_PATH_B] = rtlpriv->dm.ofdm_index[0];
+       rtlpriv->dm.delta_power_index[0] = 0;
+       rtlpriv->dm.delta_power_index_last[0] = 0;
+       rtlpriv->dm.power_index_offset[0] = 0;
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                ("  rtlpriv->dm.btxpower_tracking = %d\n",
+                 rtlpriv->dm.btxpower_tracking));
+}
+
+
+void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
+
+       rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
+       rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
+}
+
+
+void rtl8821ae_dm_init(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       spin_lock(&rtlpriv->locks.iqk_lock);
+       rtlphy->b_iqk_in_progress = false;
+       spin_unlock(&rtlpriv->locks.iqk_lock);
+
+       rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
+       rtl8821ae_dm_diginit(hw);
+       rtl8821ae_dm_init_rate_adaptive_mask(hw);
+       rtl8812ae_dm_path_diversity_init(hw);
+       rtl8821ae_dm_init_edca_turbo(hw);
+       rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw);
+#if 1
+       rtl8821ae_dm_init_dynamic_bb_powersaving(hw);
+       rtl8821ae_dm_init_dynamic_txpower(hw);
+       rtl8821ae_dm_init_txpower_tracking(hw);
+#endif
+       rtl8821ae_dm_init_dynamic_atc_switch(hw);
+}
+
+void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dig *rtl_dm_dig = &(rtlpriv->dm.dm_digtable);
+       struct rtl_mac *mac = rtl_mac(rtlpriv);
+
+       /* Determine the minimum RSSI  */
+       if ((mac->link_state < MAC80211_LINKED) &&
+           (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
+               rtl_dm_dig->min_undecorated_pwdb_for_dm = 0;
+               RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
+                        ("Not connected to any \n"));
+       }
+       if (mac->link_state >= MAC80211_LINKED) {
+               if (mac->opmode == NL80211_IFTYPE_AP ||
+                       mac->opmode == NL80211_IFTYPE_ADHOC) {
+                       rtl_dm_dig->min_undecorated_pwdb_for_dm =
+                           rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+                       RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
+                                ("AP Client PWDB = 0x%lx \n",
+                                 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb));
+               } else {
+                       rtl_dm_dig->min_undecorated_pwdb_for_dm =
+                           rtlpriv->dm.undecorated_smoothed_pwdb;
+                       RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
+                                ("STA Default Port PWDB = 0x%x \n",
+                                 rtl_dm_dig->min_undecorated_pwdb_for_dm));
+               }
+       } else {
+               rtl_dm_dig->min_undecorated_pwdb_for_dm =
+                   rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+               RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD,
+                        ("AP Ext Port or disconnet PWDB = 0x%x \n",
+                         rtl_dm_dig->min_undecorated_pwdb_for_dm));
+       }
+       RT_TRACE(COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",
+                       rtl_dm_dig->min_undecorated_pwdb_for_dm));
+}
+
+#if 0
+void  rtl8812ae_dm_rssi_dump_to_register(
+       struct ieee80211_hw *hw
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtl_write_byte(rtlpriv, RA_RSSI_DUMP, Adapter->RxStats.RxRSSIPercentage[0]);
+       rtl_write_byte(rtlpriv, RB_RSSI_DUMP, Adapter->RxStats.RxRSSIPercentage[1]);
+
+       /* Rx EVM*/
+       rtl_write_byte(rtlpriv, RS1_RX_EVM_DUMP, Adapter->RxStats.RxEVMdbm[0]);
+       rtl_write_byte(rtlpriv, RS2_RX_EVM_DUMP, Adapter->RxStats.RxEVMdbm[1]);
+
+       /*Rx SNR*/
+       rtl_write_byte(rtlpriv, RA_RX_SNR_DUMP, (u1Byte)(Adapter->RxStats.RxSNRdB[0]));
+       rtl_write_byte(rtlpriv, RB_RX_SNR_DUMP, (u1Byte)(Adapter->RxStats.RxSNRdB[1]));
+
+       /*Rx Cfo_Short*/
+       rtl_write_word(rtlpriv, RA_CFO_SHORT_DUMP, Adapter->RxStats.RxCfoShort[0]);
+       rtl_write_word(rtlpriv, RB_CFO_SHORT_DUMP, Adapter->RxStats.RxCfoShort[1]);
+
+       /*Rx Cfo_Tail*/
+       rtl_write_word(rtlpriv, RA_CFO_LONG_DUMP, Adapter->RxStats.RxCfoTail[0]);
+       rtl_write_word(rtlpriv, RB_CFO_LONG_DUMP, Adapter->RxStats.RxCfoTail[1]);
+
+}
+#endif
+
+static void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_sta_info *drv_priv;
+       u8 h2c_parameter[3] = { 0 };
+       long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
+
+
+       /* AP & ADHOC & MESH */
+       spin_lock_bh(&rtlpriv->locks.entry_list_lock);
+       list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
+               if(drv_priv->rssi_stat.undecorated_smoothed_pwdb < tmp_entry_min_pwdb)
+                       tmp_entry_min_pwdb = drv_priv->rssi_stat.undecorated_smoothed_pwdb;
+               if(drv_priv->rssi_stat.undecorated_smoothed_pwdb > tmp_entry_max_pwdb)
+                       tmp_entry_max_pwdb = drv_priv->rssi_stat.undecorated_smoothed_pwdb;
+
+               /*h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF);
+               h2c_parameter[1] = 0x20;
+               h2c_parameter[0] =  drv_priv->rssi_stat;
+               rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);*/
+       }
+       spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
+
+       /* If associated entry is found */
+       if (tmp_entry_max_pwdb != 0) {
+               rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = tmp_entry_max_pwdb;
+               RTPRINT(rtlpriv, FDM, DM_PWDB, ("EntryMaxPWDB = 0x%lx(%ld)\n",
+                       tmp_entry_max_pwdb, tmp_entry_max_pwdb));
+       } else {
+               rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0;
+       }
+       /* If associated entry is found */
+       if (tmp_entry_min_pwdb != 0xff) {
+               rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = tmp_entry_min_pwdb;
+               RTPRINT(rtlpriv, FDM, DM_PWDB, ("EntryMinPWDB = 0x%lx(%ld)\n",
+                                       tmp_entry_min_pwdb, tmp_entry_min_pwdb));
+       } else {
+               rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0;
+       }
+       /* Indicate Rx signal strength to FW. */
+       if (rtlpriv->dm.b_useramask) {
+               h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF);
+               h2c_parameter[1] = 0x20;
+               h2c_parameter[0] = 0;
+               rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);
+       } else {
+               rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undecorated_smoothed_pwdb);
+       }
+       rtl8821ae_dm_find_minimum_rssi(hw);
+       dm_digtable.rssi_val_min = rtlpriv->dm.dm_digtable.min_undecorated_pwdb_for_dm;
+}
+
+void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (dm_digtable.cur_cck_cca_thres != current_cca)
+               rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11AC, current_cca);
+
+       dm_digtable.pre_cck_cca_thres = dm_digtable.cur_cck_cca_thres;
+       dm_digtable.cur_cck_cca_thres = current_cca;
+}
+
+void rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       if(dm_digtable.stop_dig)
+               return;
+
+       if (dm_digtable.cur_igvalue != current_igi){
+               rtl_set_bbreg(hw, DM_REG_IGI_A_11AC, DM_BIT_IGI_11AC, current_igi);
+               if (rtlpriv->phy.rf_type != RF_1T1R)
+                       rtl_set_bbreg(hw, DM_REG_IGI_B_11AC, DM_BIT_IGI_11AC, current_igi);
+       }
+       //dm_digtable.pre_igvalue = dm_digtable.cur_igvalue;
+       dm_digtable.cur_igvalue = current_igi;
+}
+
+static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 dig_dynamic_min;
+       u8 dig_max_of_min;
+       bool first_connect, first_disconnect;
+       u8 dm_dig_max, dm_dig_min, offset;
+       u8 current_igi =dm_digtable.cur_igvalue;
+
+
+       RT_TRACE(COMP_DIG, DBG_LOUD,("rtl8821ae_dm_dig()==>\n"));
+
+
+       if (mac->act_scanning == true) {
+               RT_TRACE(COMP_DIG, DBG_LOUD,("rtl8821ae_dm_dig() Return: In Scan Progress \n"));
+               return;
+       }
+
+       /*add by Neil Chen to avoid PSD is processing*/
+       dig_dynamic_min = dm_digtable.dig_dynamic_min_0;
+       first_connect = (mac->link_state >= MAC80211_LINKED) &&
+                       (dm_digtable.b_media_connect_0 == false);
+       first_disconnect = (mac->link_state < MAC80211_LINKED) &&
+                       (dm_digtable.b_media_connect_0 == true);
+
+       /*1 Boundary Decision*/
+
+
+       dm_dig_max = 0x5A;
+
+       if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
+               dm_dig_min = DM_DIG_MIN;
+       else
+               dm_dig_min = 0x1C;
+
+       dig_max_of_min = DM_DIG_MAX_AP;
+
+       if (mac->link_state >= MAC80211_LINKED) {
+               if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
+                       offset = 20;
+               else
+                       offset = 10;
+
+               if ((dm_digtable.rssi_val_min + offset) > dm_dig_max)
+                       dm_digtable.rx_gain_range_max = dm_dig_max;
+               else if ((dm_digtable.rssi_val_min + offset) < dm_dig_min)
+                       dm_digtable.rx_gain_range_max = dm_dig_min;
+               else
+                       dm_digtable.rx_gain_range_max = dm_digtable.rssi_val_min + offset;
+
+               if(rtlpriv->dm.b_one_entry_only){
+                       offset = 0;
+
+                       if (dm_digtable.rssi_val_min - offset < dm_dig_min)
+                               dig_dynamic_min = dm_dig_min;
+                       else if (dm_digtable.rssi_val_min - offset > dig_max_of_min)
+                               dig_dynamic_min = dig_max_of_min;
+                       else
+                               dig_dynamic_min = dm_digtable.rssi_val_min - offset;
+
+                       RT_TRACE(COMP_DIG, DBG_LOUD,
+                               ("rtl8821ae_dm_dig() : bOneEntryOnly=TRUE,  dig_dynamic_min=0x%x\n",
+                               dig_dynamic_min));
+                       RT_TRACE(COMP_DIG, DBG_LOUD,
+                               ("rtl8821ae_dm_dig() : dm_digtable.rssi_val_min=%d",dm_digtable.
+                               rssi_val_min));
+               } else {
+                       dig_dynamic_min = dm_dig_min;
+               }
+       } else {
+               dm_digtable.rx_gain_range_max = dm_dig_max;
+               dig_dynamic_min = dm_dig_min;
+               RT_TRACE(COMP_DIG, DBG_LOUD,
+                       ("rtl8821ae_dm_dig() : No Link\n"));
+       }
+
+       if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
+               RT_TRACE(COMP_DIG, DBG_LOUD,
+                       ("rtl8821ae_dm_dig(): Abnornally false alarm case. \n"));
+
+               if (dm_digtable.large_fa_hit != 3)
+                       dm_digtable.large_fa_hit++;
+               if (dm_digtable.forbidden_igi < current_igi) {
+                       dm_digtable.forbidden_igi = current_igi;
+                       dm_digtable.large_fa_hit = 1;
+               }
+
+               if (dm_digtable.large_fa_hit >= 3) {
+                       if((dm_digtable.forbidden_igi + 1) > dm_digtable.rx_gain_range_max)
+                               dm_digtable.rx_gain_range_min = dm_digtable.rx_gain_range_max;
+                       else
+                               dm_digtable.rx_gain_range_min = (dm_digtable.forbidden_igi + 1);
+                       dm_digtable.recover_cnt = 3600;
+               }
+
+       } else {
+               /*Recovery mechanism for IGI lower bound*/
+               if (dm_digtable.recover_cnt != 0)
+                       dm_digtable.recover_cnt --;
+               else {
+                       if (dm_digtable.large_fa_hit < 3) {
+                               if ((dm_digtable.forbidden_igi -1) < dig_dynamic_min) {
+                                       dm_digtable.forbidden_igi = dig_dynamic_min;
+                                       dm_digtable.rx_gain_range_min = dig_dynamic_min;
+                                       RT_TRACE(COMP_DIG, DBG_LOUD,
+                                               ("rtl8821ae_dm_dig(): Normal Case: At Lower Bound\n"));
+                               } else {
+                                       dm_digtable.forbidden_igi --;
+                                       dm_digtable.rx_gain_range_min = (dm_digtable.forbidden_igi + 1);
+                                       RT_TRACE(COMP_DIG, DBG_LOUD,
+                                               ("rtl8821ae_dm_dig(): Normal Case: Approach Lower Bound\n"));
+                               }
+                       } else {
+                               dm_digtable.large_fa_hit = 0;
+                       }
+               }
+       }
+       RT_TRACE(COMP_DIG, DBG_LOUD,
+               ("rtl8821ae_dm_dig(): pDM_DigTable->LargeFAHit=%d\n",
+               dm_digtable.large_fa_hit));
+
+       if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10)
+               dm_digtable.rx_gain_range_min = dm_dig_min;
+
+       if (dm_digtable.rx_gain_range_min > dm_digtable.rx_gain_range_max)
+               dm_digtable.rx_gain_range_min = dm_digtable.rx_gain_range_max;
+
+       /*Adjust initial gain by false alarm*/
+       if (mac->link_state >= MAC80211_LINKED) {
+               RT_TRACE(COMP_DIG, DBG_LOUD,
+                       ("rtl8821ae_dm_dig(): DIG AfterLink\n"));
+               if (first_connect) {
+                       if (dm_digtable.rssi_val_min <= dig_max_of_min)
+                               current_igi = dm_digtable.rssi_val_min;
+                       else
+                               current_igi = dig_max_of_min;
+                       RT_TRACE(COMP_DIG, DBG_LOUD,
+                               ("rtl8821ae_dm_dig: First Connect\n"));
+               } else {
+                       if(rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
+                               current_igi = current_igi + 4;
+                       else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
+                               current_igi = current_igi + 2;
+                       else if(rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
+                               current_igi = current_igi - 2;
+
+                       if((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10)
+                               &&(rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) {
+                               current_igi = dm_digtable.rx_gain_range_min;
+                               RT_TRACE(COMP_DIG, DBG_LOUD,
+                                       ("rtl8821ae_dm_dig(): Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n"));
+                       }
+               }
+       }  else{
+               RT_TRACE(COMP_DIG, DBG_LOUD,
+                       ("rtl8821ae_dm_dig(): DIG BeforeLink\n"));
+               if (first_disconnect){
+                       current_igi = dm_digtable.rx_gain_range_min;
+                       RT_TRACE(COMP_DIG, DBG_LOUD,
+                               ("rtl8821ae_dm_dig(): First DisConnect \n"));
+               } else {
+                       /*2012.03.30 LukeLee: enable DIG before link but with very high thresholds*/
+               if (rtlpriv->falsealm_cnt.cnt_all > 2000)
+                               current_igi = current_igi + 4;
+                       else if (rtlpriv->falsealm_cnt.cnt_all > 600)
+                               current_igi = current_igi + 2;
+                       else if(rtlpriv->falsealm_cnt.cnt_all < 300)
+                               current_igi = current_igi - 2;
+                       if (current_igi >= 0x3e)
+                               current_igi = 0x3e;
+                       RT_TRACE(COMP_DIG, DBG_LOUD,("rtl8821ae_dm_dig(): England DIG \n"));
+               }
+       }
+       RT_TRACE(COMP_DIG, DBG_LOUD,
+               ("rtl8821ae_dm_dig(): DIG End Adjust IGI\n"));
+       /* Check initial gain by upper/lower bound*/
+
+       if (current_igi > dm_digtable.rx_gain_range_max)
+               current_igi = dm_digtable.rx_gain_range_max;
+       if (current_igi < dm_digtable.rx_gain_range_min)
+               current_igi = dm_digtable.rx_gain_range_min;
+
+       RT_TRACE(COMP_DIG, DBG_LOUD,
+               ("rtl8821ae_dm_dig(): rx_gain_range_max=0x%x, rx_gain_range_min=0x%x\n",
+               dm_digtable.rx_gain_range_max, dm_digtable.rx_gain_range_min));
+       RT_TRACE(COMP_DIG, DBG_LOUD,
+               ("rtl8821ae_dm_dig(): TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all));
+       RT_TRACE(COMP_DIG, DBG_LOUD,
+               ("rtl8821ae_dm_dig(): CurIGValue=0x%x\n", current_igi));
+
+       rtl8821ae_dm_write_dig(hw, current_igi);
+       dm_digtable.b_media_connect_0= ((mac->link_state >= MAC80211_LINKED) ? true :false);
+       dm_digtable.dig_dynamic_min_0 = dig_dynamic_min;
+}
+
+static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 cnt = 0;
+       struct rtl_sta_info *drv_priv;
+
+       rtlpriv->dm.b_one_entry_only = false;
+
+       if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
+               rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
+               rtlpriv->dm.b_one_entry_only = true;
+               return;
+       }
+
+       if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
+               rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
+               rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
+               spin_lock_bh(&rtlpriv->locks.entry_list_lock);
+               list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
+                       cnt ++;
+               }
+               spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
+
+               if (cnt == 1)
+                       rtlpriv->dm.b_one_entry_only = true;
+       }
+}
+
+
+static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+       u32 cck_enable =0;
+
+       /*read OFDM FA counter*/
+       falsealm_cnt->cnt_ofdm_fail = rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD);
+       falsealm_cnt->cnt_cck_fail = rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD);
+
+       cck_enable =  rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28));
+       if (cck_enable)  /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/
+               falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + falsealm_cnt->cnt_cck_fail;
+       else
+               falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail;
+
+       /*reset OFDM FA coutner*/
+       rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
+       rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
+       /* reset CCK FA counter*/
+       rtl_set_bbreg(hw,  ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
+       rtl_set_bbreg(hw,  ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
+
+       RT_TRACE(COMP_DIG, DBG_LOUD, ("Cnt_Cck_fail=%d\n",
+                       falsealm_cnt->cnt_cck_fail));
+       RT_TRACE(COMP_DIG, DBG_LOUD, ("cnt_ofdm_fail=%d\n",
+                       falsealm_cnt->cnt_ofdm_fail));
+       RT_TRACE(COMP_DIG, DBG_LOUD, ("Total False Alarm=%d\n",
+                       falsealm_cnt->cnt_all));
+}
+
+void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
+               struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       static u8 tm_trigger = 0;
+
+       if (!rtlpriv->dm.btxpower_tracking)
+               return;
+
+       if (!tm_trigger) {
+               rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16), 0x03);
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                        ("Trigger 8812 Thermal Meter!!\n"));
+               tm_trigger = 1;
+               return;
+       } else {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                        ("Schedule TxPowerTracking direct call!!\n"));
+               rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw);
+               tm_trigger = 0;
+       }
+}
+
+static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw)
+{
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       if (mac->link_state >= MAC80211_LINKED) {
+               /*if ((*rtldm->p_channel != rtldm->pre_channel )
+                       && (!mac->act_scanning)) {
+                       rtldm->pre_channel = *rtldm->p_channel;
+                       rtldm->linked_interval = 0;
+               }*/
+
+               if(rtldm->linked_interval < 3)
+                       rtldm->linked_interval ++;
+
+               if(rtldm->linked_interval == 2)
+               {
+                       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                               rtl8812ae_phy_iq_calibrate(hw, false);
+                       else
+                               rtl8821ae_phy_iq_calibrate(hw, false);
+               }
+       } else {
+               rtldm->linked_interval = 0;
+       }
+}
+
+
+void rtl8812ae_get_delta_swing_table(
+       struct ieee80211_hw *hw,
+       u8 **temperature_up_a,
+       u8 **temperature_down_a,
+       u8 **temperature_up_b,
+       u8 **temperature_down_b
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       u8 channel = rtlphy->current_channel;
+       u8 rate = rtldm->tx_rate;
+
+
+       if ( 1 <= channel && channel <= 14) {
+               if (RX_HAL_IS_CCK_RATE(rate)) {
+                       *temperature_up_a = rtldm->delta_swing_table_idx_24gccka_p;
+                       *temperature_down_a = rtldm->delta_swing_table_idx_24gccka_n;
+                       *temperature_up_b = rtldm->delta_swing_table_idx_24gcckb_p;
+                       *temperature_down_b = rtldm->delta_swing_table_idx_24gcckb_n;
+               } else {
+                       *temperature_up_a = rtldm->delta_swing_table_idx_24ga_p;
+                       *temperature_down_a = rtldm->delta_swing_table_idx_24ga_n;
+                       *temperature_up_b = rtldm->delta_swing_table_idx_24gb_p;
+                       *temperature_down_b = rtldm->delta_swing_table_idx_24gb_n;
+               }
+       } else if ( 36 <= channel && channel <= 64) {
+               *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[0];
+               *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[0];
+               *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[0];
+               *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[0];
+       } else if ( 100 <= channel && channel <= 140) {
+               *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[1];
+               *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[1];
+               *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[1];
+               *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[1];
+       } else if ( 149 <= channel && channel <= 173) {
+               *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[2];
+               *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[2];
+               *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[2];
+               *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[2];
+       } else {
+           *temperature_up_a = (u8*)rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack;
+           *temperature_down_a =(u8*)rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack;
+           *temperature_up_b = (u8*)rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack;
+           *temperature_down_b = (u8*)rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack;
+       }
+
+       return;
+}
+
+void rtl8812ae_phy_lccalibrate(
+       struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("===> rtl8812ae_phy_lccalibrate\n"));
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("<=== rtl8812ae_phy_lccalibrate\n"));
+
+}
+
+void rtl8812ae_dm_update_init_rate(
+       struct ieee80211_hw *hw,
+       u8 rate
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 p = 0;
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("Get C2H Command! Rate=0x%x\n", rate));
+
+       rtldm->tx_rate = rate;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE){
+               rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0);
+       }
+       else
+       {
+               for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
+               {
+                       rtl8812ae_dm_txpwr_track_set_pwr(hw, BBSWING, p, 0);
+               }
+       }
+
+}
+
+u8 rtl8812ae_hw_rate_to_mrate(
+       struct ieee80211_hw *hw,
+       u8 rate
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 ret_rate = MGN_1M;
+
+
+       switch(rate)
+       {
+               case DESC_RATE1M:               ret_rate = MGN_1M;              break;
+               case DESC_RATE2M:               ret_rate = MGN_2M;              break;
+               case DESC_RATE5_5M:             ret_rate = MGN_5_5M;            break;
+               case DESC_RATE11M:              ret_rate = MGN_11M;             break;
+               case DESC_RATE6M:               ret_rate = MGN_6M;              break;
+               case DESC_RATE9M:               ret_rate = MGN_9M;              break;
+               case DESC_RATE12M:              ret_rate = MGN_12M;             break;
+               case DESC_RATE18M:              ret_rate = MGN_18M;             break;
+               case DESC_RATE24M:              ret_rate = MGN_24M;             break;
+               case DESC_RATE36M:              ret_rate = MGN_36M;             break;
+               case DESC_RATE48M:              ret_rate = MGN_48M;             break;
+               case DESC_RATE54M:              ret_rate = MGN_54M;             break;
+               case DESC_RATEMCS0:     ret_rate = MGN_MCS0;            break;
+               case DESC_RATEMCS1:     ret_rate = MGN_MCS1;            break;
+               case DESC_RATEMCS2:     ret_rate = MGN_MCS2;            break;
+               case DESC_RATEMCS3:     ret_rate = MGN_MCS3;            break;
+               case DESC_RATEMCS4:     ret_rate = MGN_MCS4;            break;
+               case DESC_RATEMCS5:     ret_rate = MGN_MCS5;            break;
+               case DESC_RATEMCS6:     ret_rate = MGN_MCS6;            break;
+               case DESC_RATEMCS7:     ret_rate = MGN_MCS7;            break;
+               case DESC_RATEMCS8:     ret_rate = MGN_MCS8;            break;
+               case DESC_RATEMCS9:     ret_rate = MGN_MCS9;            break;
+               case DESC_RATEMCS10:    ret_rate = MGN_MCS10;   break;
+               case DESC_RATEMCS11:    ret_rate = MGN_MCS11;   break;
+               case DESC_RATEMCS12:    ret_rate = MGN_MCS12;   break;
+               case DESC_RATEMCS13:    ret_rate = MGN_MCS13;   break;
+               case DESC_RATEMCS14:    ret_rate = MGN_MCS14;   break;
+               case DESC_RATEMCS15:    ret_rate = MGN_MCS15;   break;
+               case DESC_RATEVHT1SS_MCS0:      ret_rate = MGN_VHT1SS_MCS0;             break;
+               case DESC_RATEVHT1SS_MCS1:      ret_rate = MGN_VHT1SS_MCS1;             break;
+               case DESC_RATEVHT1SS_MCS2:      ret_rate = MGN_VHT1SS_MCS2;             break;
+               case DESC_RATEVHT1SS_MCS3:      ret_rate = MGN_VHT1SS_MCS3;             break;
+               case DESC_RATEVHT1SS_MCS4:      ret_rate = MGN_VHT1SS_MCS4;             break;
+               case DESC_RATEVHT1SS_MCS5:      ret_rate = MGN_VHT1SS_MCS5;             break;
+               case DESC_RATEVHT1SS_MCS6:      ret_rate = MGN_VHT1SS_MCS6;             break;
+               case DESC_RATEVHT1SS_MCS7:      ret_rate = MGN_VHT1SS_MCS7;             break;
+               case DESC_RATEVHT1SS_MCS8:      ret_rate = MGN_VHT1SS_MCS8;             break;
+               case DESC_RATEVHT1SS_MCS9:      ret_rate = MGN_VHT1SS_MCS9;             break;
+               case DESC_RATEVHT2SS_MCS0:      ret_rate = MGN_VHT2SS_MCS0;             break;
+               case DESC_RATEVHT2SS_MCS1:      ret_rate = MGN_VHT2SS_MCS1;             break;
+               case DESC_RATEVHT2SS_MCS2:      ret_rate = MGN_VHT2SS_MCS2;             break;
+               case DESC_RATEVHT2SS_MCS3:      ret_rate = MGN_VHT2SS_MCS3;             break;
+               case DESC_RATEVHT2SS_MCS4:      ret_rate = MGN_VHT2SS_MCS4;             break;
+               case DESC_RATEVHT2SS_MCS5:      ret_rate = MGN_VHT2SS_MCS5;             break;
+               case DESC_RATEVHT2SS_MCS6:      ret_rate = MGN_VHT2SS_MCS6;             break;
+               case DESC_RATEVHT2SS_MCS7:      ret_rate = MGN_VHT2SS_MCS7;             break;
+               case DESC_RATEVHT2SS_MCS8:      ret_rate = MGN_VHT2SS_MCS8;             break;
+               case DESC_RATEVHT2SS_MCS9:      ret_rate = MGN_VHT2SS_MCS9;             break;
+
+               default:
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("HwRateToMRate8812(): Non supported Rate [%x]!!!\n",rate ));
+                       break;
+       }
+       return ret_rate;
+}
+
+/*-----------------------------------------------------------------------------
+ * Function:   odm_TxPwrTrackSetPwr88E()
+ *
+ * Overview:   88E change all channel tx power accordign to flag.
+ *                             OFDM & CCK are all different.
+ *
+ * Input:              NONE
+ *
+ * Output:             NONE
+ *
+ * Return:             NONE
+ *
+ * Revised History:
+ *     When            Who             Remark
+ *     04/23/2012      MHC             Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
+       enum pwr_track_control_method method, u8 rf_path, u8 channel_mapped_index)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u32 final_bb_swing_idx[2];
+       u8 pwr_tracking_limit = 26; /*+1.0dB*/
+       u8 tx_rate = 0xFF;
+       char final_ofdm_swing_index = 0;
+
+       if(rtldm->tx_rate != 0xFF)
+               tx_rate = rtl8812ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
+
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
+
+       if(tx_rate != 0xFF) { /*20130429 Mimic Modify High Rate BBSwing Limit.*/
+               /*CCK*/
+               if((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
+                       pwr_tracking_limit = 32; /*+4dB*/
+               /*OFDM*/
+               else if((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if(tx_rate == MGN_54M)
+                       pwr_tracking_limit = 28; /*+2dB*/
+               /*HT*/
+               else if((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) /*QPSK/BPSK*/
+                       pwr_tracking_limit = 34; /*+5dB*/
+               else if((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) /*16QAM*/
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) /*64QAM*/
+                       pwr_tracking_limit = 28; /*+2dB*/
+
+               else if((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10)) /*QPSK/BPSK*/
+                       pwr_tracking_limit = 34; /*+5dB*/
+               else if((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12)) /*16QAM*/
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15)) /*64QAM*/
+                       pwr_tracking_limit = 28; /*+2dB*/
+
+               /*2 VHT*/
+               else if((tx_rate >= MGN_VHT1SS_MCS0) && (tx_rate <= MGN_VHT1SS_MCS2)) /*QPSK/BPSK*/
+                       pwr_tracking_limit = 34; /*+5dB*/
+               else if((tx_rate >= MGN_VHT1SS_MCS3) && (tx_rate <= MGN_VHT1SS_MCS4)) /*16QAM*/
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if((tx_rate >= MGN_VHT1SS_MCS5)&&(tx_rate <= MGN_VHT1SS_MCS6)) /*64QAM*/
+                       pwr_tracking_limit = 28; /*+2dB*/
+               else if(tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
+                       pwr_tracking_limit = 26; /*+1dB*/
+               else if(tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
+                       pwr_tracking_limit = 24; /*+0dB*/
+               else if(tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
+                       pwr_tracking_limit = 22; /*-1dB*/
+
+               else if((tx_rate >= MGN_VHT2SS_MCS0)&&(tx_rate <= MGN_VHT2SS_MCS2)) /*QPSK/BPSK*/
+                       pwr_tracking_limit = 34; /*+5dB*/
+               else if((tx_rate >= MGN_VHT2SS_MCS3)&&(tx_rate <= MGN_VHT2SS_MCS4)) /*16QAM*/
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if((tx_rate >= MGN_VHT2SS_MCS5)&&(tx_rate <= MGN_VHT2SS_MCS6)) /*64QAM*/
+                       pwr_tracking_limit = 28; /*+2dB*/
+               else if(tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/
+                       pwr_tracking_limit = 26; /*+1dB*/
+               else if(tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/
+                       pwr_tracking_limit = 24; /*+0dB*/
+               else if(tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/
+                       pwr_tracking_limit = 22; /*-1dB*/
+               else
+                       pwr_tracking_limit = 24;
+       }
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("TxRate=0x%x, PwrTrackingLimit=%d\n", tx_rate, pwr_tracking_limit));
+
+
+       if (method == BBSWING) {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
+
+               if (rf_path == RF90_PATH_A) {
+                       final_bb_swing_idx[RF90_PATH_A] =
+                               (rtldm->ofdm_index[RF90_PATH_A] > pwr_tracking_limit) ?
+                               pwr_tracking_limit : rtldm->ofdm_index[RF90_PATH_A];
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d, \
+                               pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
+                               rtldm->ofdm_index[RF90_PATH_A], final_bb_swing_idx[RF90_PATH_A]));
+
+                       rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_bb_swing_idx[RF90_PATH_A]]);
+               } else {
+                       final_bb_swing_idx[RF90_PATH_B] =
+                               rtldm->ofdm_index[RF90_PATH_B] > pwr_tracking_limit ? \
+                               pwr_tracking_limit : rtldm->ofdm_index[RF90_PATH_B];
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, \
+                               pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n",
+                               rtldm->ofdm_index[RF90_PATH_B], final_bb_swing_idx[RF90_PATH_B]));
+
+                       rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_bb_swing_idx[RF90_PATH_B]]);
+               }
+       } else if (method == MIX_MODE) {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("pDM_Odm->DefaultOfdmIndex=%d, \
+                       pDM_Odm->Aboslute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
+                       rtldm->default_ofdm_index, rtldm->aboslute_ofdm_swing_idx[rf_path],
+                       rf_path ));
+
+
+               final_ofdm_swing_index = rtldm->default_ofdm_index + rtldm->aboslute_ofdm_swing_idx[rf_path];
+
+               if (rf_path == RF90_PATH_A) {
+                       if(final_ofdm_swing_index > pwr_tracking_limit) {     /*BBSwing higher then Limit*/
+
+                               rtldm->remnant_cck_idx = final_ofdm_swing_index - pwr_tracking_limit;
+                               /* CCK Follow the same compensate value as Path A*/
+                               rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index - pwr_tracking_limit;
+
+                               rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[pwr_tracking_limit]);
+
+                               rtldm->modify_txagc_flag_path_a = true;
+
+                               /*Set TxAGC Page C{};*/
+                               rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d \n",
+                                       pwr_tracking_limit, rtldm->remnant_ofdm_swing_idx[rf_path]));
+                       } else if (final_ofdm_swing_index < 0) {
+                               rtldm->remnant_cck_idx = final_ofdm_swing_index;
+                               /* CCK Follow the same compensate value as Path A*/
+                               rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index;
+
+                               rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[0]);
+
+                               rtldm->modify_txagc_flag_path_a = true;
+
+                               /*Set TxAGC Page C{};*/
+                               rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d \n",
+                                        rtldm->remnant_ofdm_swing_idx[rf_path]));
+                       } else {
+                               rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_ofdm_swing_index]);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_A Compensate with BBSwing , Final_OFDM_Swing_Index = %d \n",
+                                       final_ofdm_swing_index));
+
+                               if(rtldm->modify_txagc_flag_path_a) { /*If TxAGC has changed, reset TxAGC again*/
+                                       rtldm->remnant_cck_idx = 0;
+                                       rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
+
+                                       /*Set TxAGC Page C{};*/
+                                       rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
+
+                                       rtldm->modify_txagc_flag_path_a = false;
+
+                                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                               ("******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE \n"));
+                               }
+                       }
+               }
+
+               if (rf_path == RF90_PATH_B) {
+                       if(final_ofdm_swing_index > pwr_tracking_limit) {    /*BBSwing higher then Limit*/
+                               rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index - pwr_tracking_limit;
+
+                               rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[pwr_tracking_limit]);
+
+                               rtldm->modify_txagc_flag_path_b = true;
+
+                               /*Set TxAGC Page E{};*/
+                               rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_B);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d \n",
+                                       pwr_tracking_limit, rtldm->remnant_ofdm_swing_idx[rf_path]));
+                       } else if (final_ofdm_swing_index < 0) {
+                               rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index;
+
+                               rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[0]);
+
+                               rtldm->modify_txagc_flag_path_b = true;
+
+                               /*Set TxAGC Page E{};*/
+                               rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_B);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_B Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d \n",
+                                       rtldm->remnant_ofdm_swing_idx[rf_path] ));
+                       } else {
+                               rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_ofdm_swing_index]);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_B Compensate with BBSwing , Final_OFDM_Swing_Index = %d \n",
+                                       final_ofdm_swing_index));
+
+                               if(rtldm->modify_txagc_flag_path_b) { /*If TxAGC has changed, reset TxAGC again*/
+                                       rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
+
+                                       /*Set TxAGC Page E{};*/
+                                       rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_B);
+
+                                       rtldm->modify_txagc_flag_path_b = false;
+
+                                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                               ("******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE \n"));
+                               }
+                       }
+               }
+
+       } else {
+               return;
+       }
+}
+
+void rtl8812ae_dm_txpower_tracking_callback_thermalmeter
+       (struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
+       u8 thermal_value_avg_count = 0;
+       u32 thermal_value_avg = 0;
+
+       u8 ofdm_min_index = 6;  /*OFDM BB Swing should be less than +3.0dB, which is required by Arthur*/
+       u8 index_for_channel = 0; /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
+
+       /* 1. The following TWO tables decide the final index of OFDM/CCK swing table.*/
+       u8 *delta_swing_table_idx_tup_a;
+       u8 *delta_swing_table_idx_tdown_a;
+       u8 *delta_swing_table_idx_tup_b;
+       u8 *delta_swing_table_idx_tdown_b;
+
+       /*2. Initilization ( 7 steps in total )*/
+       rtl8812ae_get_delta_swing_table(hw, (u8**)&delta_swing_table_idx_tup_a,
+                                                                       (u8**)&delta_swing_table_idx_tdown_a,
+                                                                         (u8**)&delta_swing_table_idx_tup_b,
+                                                                         (u8**)&delta_swing_table_idx_tdown_b);
+
+       rtldm->btxpower_trackinginit = true;
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("===>rtl8812ae_dm_txpower_tracking_callback_thermalmeter, \
+                \n pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:\
+                %d, pDM_Odm->DefaultOfdmIndex: %d\n",
+               rtldm->bb_swing_idx_cck_base,
+               rtldm->bb_swing_idx_ofdm_base[RF90_PATH_A],
+               rtldm->default_ofdm_index));
+
+       thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER_8812A, 0xfc00);   /*0x42: RF Reg[15:10] 88E*/
+       if( ! rtldm->txpower_track_control || rtlefuse->eeprom_thermalmeter == 0 ||
+               rtlefuse->eeprom_thermalmeter == 0xFF)
+               return;
+
+
+       /* 3. Initialize ThermalValues of RFCalibrateInfo*/
+
+       if(rtlhal->reloadtxpowerindex)
+       {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("reload ofdm index for band switch\n"));
+       }
+
+       /*4. Calculate average thermal meter*/
+       rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
+       rtldm->thermalvalue_avg_index++;
+       if(rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
+               /*Average times =  c.AverageThermalNum*/
+               rtldm->thermalvalue_avg_index = 0;
+
+       for(i = 0; i < AVG_THERMAL_NUM_8812A; i++)
+       {
+               if(rtldm->thermalvalue_avg[i])
+               {
+                       thermal_value_avg += rtldm->thermalvalue_avg[i];
+                       thermal_value_avg_count++;
+               }
+       }
+
+       if(thermal_value_avg_count) /*Calculate Average ThermalValue after average enough times*/
+       {
+               thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
+                       thermal_value, rtlefuse->eeprom_thermalmeter));
+       }
+
+       /*5. Calculate delta, delta_LCK, delta_IQK.*/
+       /*"delta" here is used to determine whether thermal value changes or not.*/
+       delta = (thermal_value > rtldm->thermalvalue) ? \
+               (thermal_value - rtldm->thermalvalue): \
+               (rtldm->thermalvalue - thermal_value);
+       delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? \
+               (thermal_value - rtldm->thermalvalue_lck) : \
+               (rtldm->thermalvalue_lck - thermal_value);
+       delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? \
+               (thermal_value - rtldm->thermalvalue_iqk) : \
+               (rtldm->thermalvalue_iqk - thermal_value);
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
+               delta, delta_lck, delta_iqk));
+
+       /* 6. If necessary, do LCK.     */
+
+       if (delta_lck >= IQK_THRESHOLD) /*Delta temperature is equal to or larger than 20 centigrade.*/
+       {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("delta_LCK(%d) >= Threshold_IQK(%d)\n",
+                       delta_lck, IQK_THRESHOLD));
+               rtldm->thermalvalue_lck = thermal_value;
+               rtl8812ae_phy_lccalibrate(hw);
+       }
+
+       /*7. If necessary, move the index of swing table to adjust Tx power.*/
+
+       if (delta > 0 && rtldm->txpower_track_control)
+       {
+               /*"delta" here is used to record the absolute value of differrence.*/
+               delta = thermal_value > rtlefuse->eeprom_thermalmeter ? \
+                       (thermal_value - rtlefuse->eeprom_thermalmeter) : \
+                       (rtlefuse->eeprom_thermalmeter - thermal_value);
+
+               if (delta >= TXPWR_TRACK_TABLE_SIZE)
+                       delta = TXPWR_TRACK_TABLE_SIZE - 1;
+
+               /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
+
+               if(thermal_value > rtlefuse->eeprom_thermalmeter) {
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("delta_swing_table_idx_tup_a[%d] = %d\n",
+                                       delta, delta_swing_table_idx_tup_a[delta]));
+                       rtldm->delta_power_index_last[RF90_PATH_A] = rtldm->delta_power_index[RF90_PATH_A];
+                       rtldm->delta_power_index[RF90_PATH_A] = delta_swing_table_idx_tup_a[delta];
+
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A] =  delta_swing_table_idx_tup_a[delta];
+                       /*Record delta swing for mix mode power tracking*/
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A]));
+
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                            ("delta_swing_table_idx_tup_b[%d] = %d\n",
+                                            delta, delta_swing_table_idx_tup_b[delta]));
+                       rtldm->delta_power_index_last[RF90_PATH_B] = rtldm->delta_power_index[RF90_PATH_B];
+                       rtldm->delta_power_index[RF90_PATH_B] = delta_swing_table_idx_tup_b[delta];
+
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_B] =  delta_swing_table_idx_tup_b[delta];
+                       /*Record delta swing for mix mode power tracking*/
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_B]));
+
+               } else {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("delta_swing_table_idx_tdown_a[%d] = %d\n",
+                               delta, delta_swing_table_idx_tdown_a[delta]));
+
+                       rtldm->delta_power_index_last[RF90_PATH_A] = rtldm->delta_power_index[RF90_PATH_A];
+                       rtldm->delta_power_index[RF90_PATH_A] = -1 * delta_swing_table_idx_tdown_a[delta];
+
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A] =  -1 * delta_swing_table_idx_tdown_a[delta];
+                       /* Record delta swing for mix mode power tracking*/
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A]));
+
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
+                               delta, delta_swing_table_idx_tdown_b[delta]));
+
+                       rtldm->delta_power_index_last[RF90_PATH_B] = rtldm->delta_power_index[RF90_PATH_B];
+                       rtldm->delta_power_index[RF90_PATH_B] = -1 * delta_swing_table_idx_tdown_b[delta];
+
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_B] =  -1 * delta_swing_table_idx_tdown_b[delta];
+                       /*Record delta swing for mix mode power tracking*/
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_B]));
+               }
+
+               for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
+               {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("\n\n================================ [Path-%c] \
+                               Calculating PowerIndexOffset ================================\n",
+                               (p == RF90_PATH_A ? 'A' : 'B')));
+
+                       if (rtldm->delta_power_index[p] == rtldm->delta_power_index_last[p])
+                               /*If Thermal value changes but lookup table value still the same*/
+                               rtldm->power_index_offset[p] = 0;
+                       else
+                               rtldm->power_index_offset[p] =
+                                       rtldm->delta_power_index[p] - rtldm->delta_power_index_last[p];
+                               /*Power Index Diff between 2 times Power Tracking*/
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
+                               (p == RF90_PATH_A ? 'A' : 'B'),
+                               rtldm->power_index_offset[p],
+                               rtldm->delta_power_index[p] ,
+                               rtldm->delta_power_index_last[p]));
+
+                       rtldm->ofdm_index[p] =
+                                       rtldm->bb_swing_idx_ofdm_base[p] + rtldm->power_index_offset[p];
+                       rtldm->cck_index =
+                                       rtldm->bb_swing_idx_cck_base + rtldm->power_index_offset[p];
+
+                       rtldm->bb_swing_idx_cck = rtldm->cck_index;
+                       rtldm->bb_swing_idx_ofdm[p] = rtldm->ofdm_index[p];
+
+                       /*************Print BB Swing Base and Index Offset*************/
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
+                               rtldm->bb_swing_idx_cck,
+                               rtldm->bb_swing_idx_cck_base,
+                               rtldm->power_index_offset[p]));
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
+                               rtldm->bb_swing_idx_ofdm[p],
+                               (p == RF90_PATH_A ? 'A' : 'B'),
+                               rtldm->bb_swing_idx_ofdm_base[p],
+                               rtldm->power_index_offset[p]));
+
+                       /*7.1 Handle boundary conditions of index.*/
+
+
+                       if(rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE -1)
+                       {
+                               rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE -1;
+                       }
+                       else if (rtldm->ofdm_index[p] < ofdm_min_index)
+                       {
+                               rtldm->ofdm_index[p] = ofdm_min_index;
+                       }
+               }
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("\n\n======================================================\
+                       ==================================================\n"));
+               if(rtldm->cck_index > TXSCALE_TABLE_SIZE -1)
+                       rtldm->cck_index = TXSCALE_TABLE_SIZE -1;
+               else if (rtldm->cck_index < 0)
+                       rtldm->cck_index = 0;
+       } else {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("The thermal meter is unchanged or TxPowerTracking OFF(%d): \
+                       ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
+                       rtldm->txpower_track_control,
+                       thermal_value,
+                       rtldm->thermalvalue));
+
+               for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
+                       rtldm->power_index_offset[p] = 0;
+       }
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
+               rtldm->cck_index, rtldm->bb_swing_idx_cck_base));       /*Print Swing base & current*/
+       for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
+       {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
+                       rtldm->ofdm_index[p],
+                       (p == RF90_PATH_A ? 'A' : 'B'),
+                       rtldm->bb_swing_idx_ofdm_base[p]));
+       }
+
+       if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
+               rtldm->power_index_offset[RF90_PATH_B] != 0 ) &&
+               rtldm->txpower_track_control)
+       {
+               /*7.2 Configure the Swing Table to adjust Tx Power.*/
+               /*Always TRUE after Tx Power is adjusted by power tracking.*/
+               /*
+                 2012/04/23 MH According to Luke's suggestion, we can not write BB digital
+                 to increase TX power. Otherwise, EVM will be bad.
+
+                 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
+               */
+               if (thermal_value > rtldm->thermalvalue)
+               {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+                               rtldm->power_index_offset[RF90_PATH_A],
+                               delta, thermal_value,
+                               rtlefuse->eeprom_thermalmeter,
+                               rtldm->thermalvalue));
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature Increasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+                               rtldm->power_index_offset[RF90_PATH_B],
+                               delta, thermal_value,
+                               rtlefuse->eeprom_thermalmeter,
+                               rtldm->thermalvalue));
+
+               } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+                               rtldm->power_index_offset[RF90_PATH_A],
+                               delta, thermal_value,
+                               rtlefuse->eeprom_thermalmeter,
+                               rtldm->thermalvalue));
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+                               rtldm->power_index_offset[RF90_PATH_B],
+                               delta, thermal_value,
+                               rtlefuse->eeprom_thermalmeter,
+                               rtldm->thermalvalue));
+               }
+
+               if (thermal_value > rtlefuse->eeprom_thermalmeter) {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature(%d) higher than PG value(%d)\n",
+                               thermal_value, rtlefuse->eeprom_thermalmeter));
+
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("**********Enter POWER Tracking MIX_MODE**********\n"));
+                       for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
+                                       rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0);
+
+               } else {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature(%d) lower than PG value(%d)\n",
+                               thermal_value, rtlefuse->eeprom_thermalmeter));
+
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("**********Enter POWER Tracking MIX_MODE**********\n"));
+                       for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
+                               rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, index_for_channel);
+
+               }
+
+               rtldm->bb_swing_idx_cck_base = rtldm->bb_swing_idx_cck;   /*Record last time Power Tracking result as base.*/
+               for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
+                               rtldm->bb_swing_idx_ofdm_base[p] = rtldm->bb_swing_idx_ofdm[p];
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
+                                       rtldm->thermalvalue, thermal_value));
+
+               rtldm->thermalvalue = thermal_value;         /*Record last Power Tracking Thermal Value*/
+
+       }
+       /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
+       if ((delta_iqk >= IQK_THRESHOLD)) {
+
+               if ( !rtlphy->b_iqk_in_progress) {
+
+                       spin_lock(&rtlpriv->locks.iqk_lock);
+                       rtlphy->b_iqk_in_progress = true;
+                       spin_unlock(&rtlpriv->locks.iqk_lock);
+
+                       rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8);
+
+                       spin_lock(&rtlpriv->locks.iqk_lock);
+                       rtlphy->b_iqk_in_progress = false;
+                       spin_unlock(&rtlpriv->locks.iqk_lock);
+               }
+       }
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n"));
+}
+
+
+void rtl8821ae_get_delta_swing_table(
+       struct ieee80211_hw *hw,
+       u8 **temperature_up_a,
+       u8 **temperature_down_a,
+       u8 **temperature_up_b,
+       u8 **temperature_down_b
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       u8 channel = rtlphy->current_channel;
+       u8 rate = rtldm->tx_rate;
+
+
+       if ( 1 <= channel && channel <= 14) {
+               if (RX_HAL_IS_CCK_RATE(rate)) {
+                       *temperature_up_a = rtldm->delta_swing_table_idx_24gccka_p;
+                       *temperature_down_a = rtldm->delta_swing_table_idx_24gccka_n;
+                       *temperature_up_b = rtldm->delta_swing_table_idx_24gcckb_p;
+                       *temperature_down_b = rtldm->delta_swing_table_idx_24gcckb_n;
+               } else {
+                       *temperature_up_a = rtldm->delta_swing_table_idx_24ga_p;
+                       *temperature_down_a = rtldm->delta_swing_table_idx_24ga_n;
+                       *temperature_up_b = rtldm->delta_swing_table_idx_24gb_p;
+                       *temperature_down_b = rtldm->delta_swing_table_idx_24gb_n;
+               }
+       } else if ( 36 <= channel && channel <= 64) {
+               *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[0];
+               *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[0];
+               *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[0];
+               *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[0];
+       } else if ( 100 <= channel && channel <= 140) {
+               *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[1];
+               *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[1];
+               *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[1];
+               *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[1];
+       } else if ( 149 <= channel && channel <= 173) {
+               *temperature_up_a = rtldm->delta_swing_table_idx_5ga_p[2];
+               *temperature_down_a = rtldm->delta_swing_table_idx_5ga_n[2];
+               *temperature_up_b = rtldm->delta_swing_table_idx_5gb_p[2];
+               *temperature_down_b = rtldm->delta_swing_table_idx_5gb_n[2];
+       } else {
+           *temperature_up_a = (u8*)rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack;
+           *temperature_down_a =(u8*)rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack;
+           *temperature_up_b = (u8*)rtl8818e_delta_swing_table_idx_24gb_p_txpwrtrack;
+           *temperature_down_b = (u8*)rtl8818e_delta_swing_table_idx_24gb_n_txpwrtrack;
+       }
+
+       return;
+}
+
+void rtl8821ae_phy_lccalibrate(
+       struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("===> rtl8812ae_phy_lccalibrate\n"));
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("<=== rtl8812ae_phy_lccalibrate\n"));
+
+}
+
+/*-----------------------------------------------------------------------------
+ * Function:   odm_TxPwrTrackSetPwr88E()
+ *
+ * Overview:   88E change all channel tx power accordign to flag.
+ *                             OFDM & CCK are all different.
+ *
+ * Input:              NONE
+ *
+ * Output:             NONE
+ *
+ * Return:             NONE
+ *
+ * Revised History:
+ *     When            Who             Remark
+ *     04/23/2012      MHC             Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
+       enum pwr_track_control_method method, u8 rf_path, u8 channel_mapped_index)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u32 final_bb_swing_idx[1];
+       u8 pwr_tracking_limit = 26; /*+1.0dB*/
+       u8 tx_rate = 0xFF;
+       char final_ofdm_swing_index = 0;
+
+       if(rtldm->tx_rate != 0xFF)
+               tx_rate = rtl8812ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
+
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
+
+       if(tx_rate != 0xFF) { /*20130429 Mimic Modify High Rate BBSwing Limit.*/
+               /*CCK*/
+               if((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
+                       pwr_tracking_limit = 32; /*+4dB*/
+               /*OFDM*/
+               else if((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if(tx_rate == MGN_54M)
+                       pwr_tracking_limit = 28; /*+2dB*/
+               /*HT*/
+               else if((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) /*QPSK/BPSK*/
+                       pwr_tracking_limit = 34; /*+5dB*/
+               else if((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) /*16QAM*/
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) /*64QAM*/
+                       pwr_tracking_limit = 28; /*+2dB*/
+#if 0
+               else if((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10)) /*QPSK/BPSK*/
+                       pwr_tracking_limit = 34; /*+5dB*/
+               else if((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12)) /*16QAM*/
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15)) /*64QAM*/
+                       pwr_tracking_limit = 28; /*+2dB*/
+#endif
+               /*2 VHT*/
+               else if((tx_rate >= MGN_VHT1SS_MCS0) && (tx_rate <= MGN_VHT1SS_MCS2)) /*QPSK/BPSK*/
+                       pwr_tracking_limit = 34; /*+5dB*/
+               else if((tx_rate >= MGN_VHT1SS_MCS3) && (tx_rate <= MGN_VHT1SS_MCS4)) /*16QAM*/
+                       pwr_tracking_limit = 30; /*+3dB*/
+               else if((tx_rate >= MGN_VHT1SS_MCS5)&&(tx_rate <= MGN_VHT1SS_MCS6)) /*64QAM*/
+                       pwr_tracking_limit = 28; /*+2dB*/
+               else if(tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
+                       pwr_tracking_limit = 26; /*+1dB*/
+               else if(tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
+                       pwr_tracking_limit = 24; /*+0dB*/
+               else if(tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
+                       pwr_tracking_limit = 22; /*-1dB*/
+               else
+                       pwr_tracking_limit = 24;
+       }
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("TxRate=0x%x, PwrTrackingLimit=%d\n", tx_rate, pwr_tracking_limit));
+
+
+       if (method == BBSWING) {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("===>rtl8812ae_dm_txpwr_track_set_pwr\n"));
+
+               if (rf_path == RF90_PATH_A) {
+                       final_bb_swing_idx[RF90_PATH_A] =
+                               (rtldm->ofdm_index[RF90_PATH_A] > pwr_tracking_limit) ?
+                               pwr_tracking_limit : rtldm->ofdm_index[RF90_PATH_A];
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d, \
+                               pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
+                               rtldm->ofdm_index[RF90_PATH_A], final_bb_swing_idx[RF90_PATH_A]));
+
+                       rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_bb_swing_idx[RF90_PATH_A]]);
+               }
+       } else if (method == MIX_MODE) {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("pDM_Odm->DefaultOfdmIndex=%d, \
+                       pDM_Odm->Aboslute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
+                       rtldm->default_ofdm_index, rtldm->aboslute_ofdm_swing_idx[rf_path],
+                       rf_path ));
+
+
+               final_ofdm_swing_index = rtldm->default_ofdm_index + rtldm->aboslute_ofdm_swing_idx[rf_path];
+
+               if (rf_path == RF90_PATH_A) {
+                       if(final_ofdm_swing_index > pwr_tracking_limit) {     /*BBSwing higher then Limit*/
+
+                               rtldm->remnant_cck_idx = final_ofdm_swing_index - pwr_tracking_limit;
+                               /* CCK Follow the same compensate value as Path A*/
+                               rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index - pwr_tracking_limit;
+
+                               rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[pwr_tracking_limit]);
+
+                               rtldm->modify_txagc_flag_path_a = true;
+
+                               /*Set TxAGC Page C{};*/
+                               rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d \n",
+                                       pwr_tracking_limit, rtldm->remnant_ofdm_swing_idx[rf_path]));
+                       } else if (final_ofdm_swing_index < 0) {
+                               rtldm->remnant_cck_idx = final_ofdm_swing_index;
+                               /* CCK Follow the same compensate value as Path A*/
+                               rtldm->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index;
+
+                               rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[0]);
+
+                               rtldm->modify_txagc_flag_path_a = true;
+
+                               /*Set TxAGC Page C{};*/
+                               rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d \n",
+                                        rtldm->remnant_ofdm_swing_idx[rf_path]));
+                       } else {
+                               rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, rtl8812ae_txscaling_table[final_ofdm_swing_index]);
+
+                               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("******Path_A Compensate with BBSwing , Final_OFDM_Swing_Index = %d \n",
+                                       final_ofdm_swing_index));
+
+                               if(rtldm->modify_txagc_flag_path_a) { /*If TxAGC has changed, reset TxAGC again*/
+                                       rtldm->remnant_cck_idx = 0;
+                                       rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
+
+                                       /*Set TxAGC Page C{};*/
+                                       rtl8821ae_phy_set_txpower_level_by_path(hw, rtlphy->current_channel, RF90_PATH_A);
+
+                                       rtldm->modify_txagc_flag_path_a = false;
+
+                                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                               ("******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE \n"));
+                               }
+                       }
+               }
+
+       } else {
+               return;
+       }
+}
+
+
+void rtl8821ae_dm_txpower_tracking_callback_thermalmeter
+       (struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
+       u8 thermal_value_avg_count = 0;
+       u32 thermal_value_avg = 0;
+
+       u8 ofdm_min_index = 6;  /*OFDM BB Swing should be less than +3.0dB, which is required by Arthur*/
+       u8 index_for_channel = 0; /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
+
+       /* 1. The following TWO tables decide the final index of OFDM/CCK swing table.*/
+       u8 *delta_swing_table_idx_tup_a;
+       u8 *delta_swing_table_idx_tdown_a;
+       u8 *delta_swing_table_idx_tup_b;
+       u8 *delta_swing_table_idx_tdown_b;
+
+       /*2. Initilization ( 7 steps in total )*/
+       rtl8821ae_get_delta_swing_table(hw, (u8**)&delta_swing_table_idx_tup_a,
+                                                                       (u8**)&delta_swing_table_idx_tdown_a,
+                                                                         (u8**)&delta_swing_table_idx_tup_b,
+                                                                         (u8**)&delta_swing_table_idx_tdown_b);
+
+       rtldm->btxpower_trackinginit = true;
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("===>rtl8812ae_dm_txpower_tracking_callback_thermalmeter, \
+                \n pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:\
+                %d, pDM_Odm->DefaultOfdmIndex: %d\n",
+               rtldm->bb_swing_idx_cck_base,
+               rtldm->bb_swing_idx_ofdm_base[RF90_PATH_A],
+               rtldm->default_ofdm_index));
+
+       thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER_8812A, 0xfc00);   /*0x42: RF Reg[15:10] 88E*/
+       if( ! rtldm->txpower_track_control || rtlefuse->eeprom_thermalmeter == 0 ||
+               rtlefuse->eeprom_thermalmeter == 0xFF)
+               return;
+
+
+       /* 3. Initialize ThermalValues of RFCalibrateInfo*/
+
+       if(rtlhal->reloadtxpowerindex)
+       {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("reload ofdm index for band switch\n"));
+       }
+
+       /*4. Calculate average thermal meter*/
+       rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
+       rtldm->thermalvalue_avg_index++;
+       if(rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
+               /*Average times =  c.AverageThermalNum*/
+               rtldm->thermalvalue_avg_index = 0;
+
+       for(i = 0; i < AVG_THERMAL_NUM_8812A; i++)
+       {
+               if(rtldm->thermalvalue_avg[i])
+               {
+                       thermal_value_avg += rtldm->thermalvalue_avg[i];
+                       thermal_value_avg_count++;
+               }
+       }
+
+       if(thermal_value_avg_count) /*Calculate Average ThermalValue after average enough times*/
+       {
+               thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
+                       thermal_value, rtlefuse->eeprom_thermalmeter));
+       }
+
+       /*5. Calculate delta, delta_LCK, delta_IQK.*/
+       /*"delta" here is used to determine whether thermal value changes or not.*/
+       delta = (thermal_value > rtldm->thermalvalue) ? \
+               (thermal_value - rtldm->thermalvalue): \
+               (rtldm->thermalvalue - thermal_value);
+       delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? \
+               (thermal_value - rtldm->thermalvalue_lck) : \
+               (rtldm->thermalvalue_lck - thermal_value);
+       delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? \
+               (thermal_value - rtldm->thermalvalue_iqk) : \
+               (rtldm->thermalvalue_iqk - thermal_value);
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
+               delta, delta_lck, delta_iqk));
+
+       /* 6. If necessary, do LCK.     */
+
+       if (delta_lck >= IQK_THRESHOLD) /*Delta temperature is equal to or larger than 20 centigrade.*/
+       {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("delta_LCK(%d) >= Threshold_IQK(%d)\n",
+                       delta_lck, IQK_THRESHOLD));
+               rtldm->thermalvalue_lck = thermal_value;
+               rtl8821ae_phy_lccalibrate(hw);
+       }
+
+       /*7. If necessary, move the index of swing table to adjust Tx power.*/
+
+       if (delta > 0 && rtldm->txpower_track_control)
+       {
+               /*"delta" here is used to record the absolute value of differrence.*/
+               delta = thermal_value > rtlefuse->eeprom_thermalmeter ? \
+                       (thermal_value - rtlefuse->eeprom_thermalmeter) : \
+                       (rtlefuse->eeprom_thermalmeter - thermal_value);
+
+               if (delta >= TXSCALE_TABLE_SIZE)
+                       delta = TXSCALE_TABLE_SIZE - 1;
+
+               /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
+
+               if(thermal_value > rtlefuse->eeprom_thermalmeter) {
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("delta_swing_table_idx_tup_a[%d] = %d\n",
+                                       delta, delta_swing_table_idx_tup_a[delta]));
+                       rtldm->delta_power_index_last[RF90_PATH_A] = rtldm->delta_power_index[RF90_PATH_A];
+                       rtldm->delta_power_index[RF90_PATH_A] = delta_swing_table_idx_tup_a[delta];
+
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A] =  delta_swing_table_idx_tup_a[delta];
+                       /*Record delta swing for mix mode power tracking*/
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("******Temp is higher and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A]));
+
+               } else {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("delta_swing_table_idx_tdown_a[%d] = %d\n",
+                               delta, delta_swing_table_idx_tdown_a[delta]));
+
+                       rtldm->delta_power_index_last[RF90_PATH_A] = rtldm->delta_power_index[RF90_PATH_A];
+                       rtldm->delta_power_index[RF90_PATH_A] = -1 * delta_swing_table_idx_tdown_a[delta];
+
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A] =  -1 * delta_swing_table_idx_tdown_a[delta];
+                       /* Record delta swing for mix mode power tracking*/
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("******Temp is lower and pDM_Odm->Aboslute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
+                       rtldm->aboslute_ofdm_swing_idx[RF90_PATH_A]));
+               }
+
+               for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
+               {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("\n\n================================ [Path-%c] \
+                               Calculating PowerIndexOffset ================================\n",
+                               (p == RF90_PATH_A ? 'A' : 'B')));
+
+                       if (rtldm->delta_power_index[p] == rtldm->delta_power_index_last[p])
+                               /*If Thermal value changes but lookup table value still the same*/
+                               rtldm->power_index_offset[p] = 0;
+                       else
+                               rtldm->power_index_offset[p] =
+                                       rtldm->delta_power_index[p] - rtldm->delta_power_index_last[p];
+                               /*Power Index Diff between 2 times Power Tracking*/
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
+                               (p == RF90_PATH_A ? 'A' : 'B'),
+                               rtldm->power_index_offset[p],
+                               rtldm->delta_power_index[p] ,
+                               rtldm->delta_power_index_last[p]));
+
+                       rtldm->ofdm_index[p] =
+                                       rtldm->bb_swing_idx_ofdm_base[p] + rtldm->power_index_offset[p];
+                       rtldm->cck_index =
+                                       rtldm->bb_swing_idx_cck_base + rtldm->power_index_offset[p];
+
+                       rtldm->bb_swing_idx_cck = rtldm->cck_index;
+                       rtldm->bb_swing_idx_ofdm[p] = rtldm->ofdm_index[p];
+
+                       /*************Print BB Swing Base and Index Offset*************/
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
+                               rtldm->bb_swing_idx_cck,
+                               rtldm->bb_swing_idx_cck_base,
+                               rtldm->power_index_offset[p]));
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
+                               rtldm->bb_swing_idx_ofdm[p],
+                               (p == RF90_PATH_A ? 'A' : 'B'),
+                               rtldm->bb_swing_idx_ofdm_base[p],
+                               rtldm->power_index_offset[p]));
+
+                       /*7.1 Handle boundary conditions of index.*/
+
+
+                       if(rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE -1)
+                       {
+                               rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE -1;
+                       }
+                       else if (rtldm->ofdm_index[p] < ofdm_min_index)
+                       {
+                               rtldm->ofdm_index[p] = ofdm_min_index;
+                       }
+               }
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("\n\n======================================================\
+                       ==================================================\n"));
+               if(rtldm->cck_index > TXSCALE_TABLE_SIZE -1)
+                       rtldm->cck_index = TXSCALE_TABLE_SIZE -1;
+               else if (rtldm->cck_index < 0)
+                       rtldm->cck_index = 0;
+       } else {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("The thermal meter is unchanged or TxPowerTracking OFF(%d): \
+                       ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
+                       rtldm->txpower_track_control,
+                       thermal_value,
+                       rtldm->thermalvalue));
+
+               for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
+                       rtldm->power_index_offset[p] = 0;
+       }
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
+               rtldm->cck_index, rtldm->bb_swing_idx_cck_base));       /*Print Swing base & current*/
+       for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
+       {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                       ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
+                       rtldm->ofdm_index[p],
+                       (p == RF90_PATH_A ? 'A' : 'B'),
+                       rtldm->bb_swing_idx_ofdm_base[p]));
+       }
+
+       if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
+               rtldm->power_index_offset[RF90_PATH_B] != 0 ) &&
+               rtldm->txpower_track_control)
+       {
+               /*7.2 Configure the Swing Table to adjust Tx Power.*/
+               /*Always TRUE after Tx Power is adjusted by power tracking.*/
+               /*
+                 2012/04/23 MH According to Luke's suggestion, we can not write BB digital
+                 to increase TX power. Otherwise, EVM will be bad.
+
+                 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E.
+               */
+               if (thermal_value > rtldm->thermalvalue)
+               {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+                               rtldm->power_index_offset[RF90_PATH_A],
+                               delta, thermal_value,
+                               rtlefuse->eeprom_thermalmeter,
+                               rtldm->thermalvalue));
+               } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+                               rtldm->power_index_offset[RF90_PATH_A],
+                               delta, thermal_value,
+                               rtlefuse->eeprom_thermalmeter,
+                               rtldm->thermalvalue));
+               }
+
+               if (thermal_value > rtlefuse->eeprom_thermalmeter) {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature(%d) higher than PG value(%d)\n",
+                               thermal_value, rtlefuse->eeprom_thermalmeter));
+
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("**********Enter POWER Tracking MIX_MODE**********\n"));
+                       for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
+                                       rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, index_for_channel);
+
+               } else {
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("Temperature(%d) lower than PG value(%d)\n",
+                               thermal_value, rtlefuse->eeprom_thermalmeter));
+
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                               ("**********Enter POWER Tracking MIX_MODE**********\n"));
+                       for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
+                               rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, index_for_channel);
+
+               }
+
+               rtldm->bb_swing_idx_cck_base = rtldm->bb_swing_idx_cck;   /*Record last time Power Tracking result as base.*/
+               for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
+                               rtldm->bb_swing_idx_ofdm_base[p] = rtldm->bb_swing_idx_ofdm[p];
+
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                                       ("pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
+                                       rtldm->thermalvalue, thermal_value));
+
+               rtldm->thermalvalue = thermal_value;         /*Record last Power Tracking Thermal Value*/
+
+       }
+       /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/
+       if ((delta_iqk >= IQK_THRESHOLD)) {
+
+               if ( !rtlphy->b_iqk_in_progress) {
+
+                       spin_lock(&rtlpriv->locks.iqk_lock);
+                       rtlphy->b_iqk_in_progress = true;
+                       spin_unlock(&rtlpriv->locks.iqk_lock);
+
+                       rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8);
+
+                       spin_lock(&rtlpriv->locks.iqk_lock);
+                       rtlphy->b_iqk_in_progress = false;
+                       spin_unlock(&rtlpriv->locks.iqk_lock);
+               }
+       }
+
+       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+               ("<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n"));
+}
+
+
+void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       static u8 tm_trigger = 0;
+
+       //if (!rtlpriv->dm.btxpower_tracking)
+       //      return;
+
+       if (!tm_trigger) {
+               rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16),
+                             0x03);
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                        ("Trigger 8821ae Thermal Meter!!\n"));
+               tm_trigger = 1;
+               return;
+       } else {
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,
+                        ("Schedule TxPowerTracking !!\n"));
+
+               rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw);
+               tm_trigger = 0;
+       }
+}
+
+
+void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *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));
+       struct rate_adaptive *p_ra = &(rtlpriv->ra);
+       u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra;
+       u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
+       u8 go_up_gap = 5;
+       struct ieee80211_sta *sta = NULL;
+
+       if (is_hal_stop(rtlhal)) {
+               RT_TRACE(COMP_RATE, DBG_LOUD,
+                        ("driver is going to unload\n"));
+               return;
+       }
+
+       if (!rtlpriv->dm.b_useramask) {
+               RT_TRACE(COMP_RATE, DBG_LOUD,
+                        ("driver does not control rate adaptive mask\n"));
+               return;
+       }
+
+       if (mac->link_state == MAC80211_LINKED &&
+               mac->opmode == NL80211_IFTYPE_STATION) {
+
+               switch (p_ra->pre_ratr_state) {
+                       case DM_RATR_STA_MIDDLE:
+                               high_rssithresh_for_ra += go_up_gap;
+                               break;
+                       case DM_RATR_STA_LOW:
+                               high_rssithresh_for_ra += go_up_gap;
+                               low_rssithresh_for_ra += go_up_gap;
+                               break;
+                       default:
+                               break;
+               }
+
+               if (rtlpriv->dm.undecorated_smoothed_pwdb >
+                   (long)high_rssithresh_for_ra)
+                       p_ra->ratr_state = DM_RATR_STA_HIGH;
+               else if (rtlpriv->dm.undecorated_smoothed_pwdb >
+                        (long)low_rssithresh_for_ra)
+                       p_ra->ratr_state = DM_RATR_STA_MIDDLE;
+               else
+                       p_ra->ratr_state = DM_RATR_STA_LOW;
+
+               if (p_ra->pre_ratr_state != p_ra->ratr_state ) {
+                       RT_TRACE(COMP_RATE, DBG_LOUD,
+                                ("RSSI = %ld\n",
+                                 rtlpriv->dm.undecorated_smoothed_pwdb));
+                       RT_TRACE(COMP_RATE, DBG_LOUD,
+                                ("RSSI_LEVEL = %d\n", p_ra->ratr_state));
+                       RT_TRACE(COMP_RATE, DBG_LOUD,
+                                ("PreState = %d, CurState = %d\n",
+                                 p_ra->pre_ratr_state, p_ra->ratr_state));
+
+                       rcu_read_lock();
+                       sta = rtl_find_sta(hw, mac->bssid);
+                       if (sta)
+                       rtlpriv->cfg->ops->update_rate_tbl(hw, sta, p_ra->ratr_state);
+                       rcu_read_unlock();
+
+                       p_ra->pre_ratr_state = p_ra->ratr_state;
+               }
+       }
+}
+
+bool rtl8821ae_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->btcoexist.btc_ops->btc_is_disable_edca_turbo(rtlpriv))
+               return true;
+       if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
+               return true;
+
+       return false;
+}
+
+void rtl8821ae_dm_edca_choose_traffic_idx(
+       struct ieee80211_hw *hw, u64 cur_tx_bytes, u64 cur_rx_bytes, bool b_bias_on_rx,
+       bool *pb_is_cur_rdl_state)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if(b_bias_on_rx)
+       {
+               if (cur_tx_bytes > (cur_rx_bytes*4)) {
+                       *pb_is_cur_rdl_state = false;
+                       RT_TRACE(COMP_TURBO, DBG_LOUD,
+                               ("Uplink Traffic\n "));
+               } else {
+                       *pb_is_cur_rdl_state = true;
+                       RT_TRACE(COMP_TURBO, DBG_LOUD,
+                               ("Balance Traffic\n"));
+               }
+       } else {
+               if (cur_rx_bytes > (cur_tx_bytes*4)) {
+                       *pb_is_cur_rdl_state = true;
+                       RT_TRACE(COMP_TURBO, DBG_LOUD,
+                               ("Downlink      Traffic\n"));
+               } else {
+                       *pb_is_cur_rdl_state = false;
+                       RT_TRACE(COMP_TURBO, DBG_LOUD,
+                               ("Balance Traffic\n"));
+               }
+       }
+       return ;
+}
+
+static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_dm *rtldm =  rtl_dm(rtl_priv(hw));
+
+       /*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/
+       u64 cur_tx_ok_cnt = 0;
+       u64 cur_rx_ok_cnt = 0;
+       u32 edca_be_ul = 0x5ea42b;
+       u32 edca_be_dl = 0x5ea42b;
+       u32 edca_be = 0x5ea42b;
+       u8 iot_peer = 0;
+       bool *pb_is_cur_rdl_state = NULL;
+       bool b_last_is_cur_rdl_state = false;
+       bool b_bias_on_rx = false;
+       bool b_edca_turbo_on = false;
+
+       RT_TRACE(COMP_TURBO, DBG_LOUD,
+               ("rtl8821ae_dm_check_edca_turbo=====>"));
+       RT_TRACE(COMP_TURBO, DBG_LOUD,
+               ("Orginial BE PARAM: 0x%x\n",
+               rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N)));
+
+       /*===============================
+       list paramter for different platform
+       ===============================*/
+       b_last_is_cur_rdl_state = rtlpriv->dm.bis_cur_rdlstate;
+       pb_is_cur_rdl_state = &( rtlpriv->dm.bis_cur_rdlstate);
+
+       cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt;
+       cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt;
+
+       rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
+       rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
+
+       iot_peer = rtlpriv->mac80211.vendor;
+       b_bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ?
+                      true : false;
+       b_edca_turbo_on = ((!rtlpriv->dm.bis_any_nonbepkts) &&
+                          (!rtlpriv->dm.b_disable_framebursting)) ?
+                          true : false;
+
+       /*if (rtl8821ae_dm_is_edca_turbo_disable(hw))
+               goto dm_CheckEdcaTurbo_EXIT;*/
+
+       if ((iot_peer == PEER_CISCO) && (mac->mode == WIRELESS_MODE_N_24G))
+       {
+               edca_be_dl = edca_setting_dl[iot_peer];
+               edca_be_ul = edca_setting_ul[iot_peer];
+       }
+
+       RT_TRACE(COMP_TURBO, DBG_LOUD,
+               ("bIsAnyNonBEPkts : 0x%x  bDisableFrameBursting : 0x%x  \n",
+               rtlpriv->dm.bis_any_nonbepkts, rtlpriv->dm.b_disable_framebursting));
+
+       RT_TRACE(COMP_TURBO, DBG_LOUD,
+                       ("bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",
+                       b_edca_turbo_on, b_bias_on_rx));
+
+       if (b_edca_turbo_on) {
+               RT_TRACE(COMP_TURBO, DBG_LOUD,
+                       ("curTxOkCnt : 0x%lx \n",cur_tx_ok_cnt));
+               RT_TRACE(COMP_TURBO, DBG_LOUD,
+                       ("curRxOkCnt : 0x%lx \n",cur_rx_ok_cnt));
+               if(b_bias_on_rx)
+                       rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
+                               cur_rx_ok_cnt, true, pb_is_cur_rdl_state);
+               else
+                       rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
+                               cur_rx_ok_cnt, false, pb_is_cur_rdl_state);
+
+               edca_be = ((*pb_is_cur_rdl_state) == true) ? edca_be_dl : edca_be_ul;
+
+               rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be);
+
+               RT_TRACE(COMP_TURBO, DBG_LOUD,
+                       ("EDCA Turbo on: EDCA_BE:0x%x\n", edca_be));
+
+               rtlpriv->dm.bcurrent_turbo_edca = true;
+
+               RT_TRACE(COMP_TURBO, DBG_LOUD,
+                       ("EDCA_BE_DL : 0x%x  EDCA_BE_UL : 0x%x  EDCA_BE : 0x%x  \n",
+                       edca_be_dl, edca_be_ul, edca_be));
+       } else {
+               if (rtlpriv->dm.bcurrent_turbo_edca) {
+                       u8 tmp = AC0_BE;
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
+                                                     (u8 *) (&tmp));
+               }
+               rtlpriv->dm.bcurrent_turbo_edca = false;
+       }
+
+/* dm_CheckEdcaTurbo_EXIT: */
+       rtlpriv->dm.bis_any_nonbepkts = false;
+       rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
+       rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
+}
+
+static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 cur_cck_cca_thresh;
+
+       if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
+               /*dm_digtable.rssi_val_min = rtl8821ae_dm_initial_gain_min_pwdb(hw);*/
+               if (dm_digtable.rssi_val_min > 25)
+                       cur_cck_cca_thresh = 0xcd;
+               else if ((dm_digtable.rssi_val_min <= 25) && (dm_digtable.rssi_val_min > 10))
+                       cur_cck_cca_thresh = 0x83;
+               else {
+                       if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
+                               cur_cck_cca_thresh = 0x83;
+                       else
+                               cur_cck_cca_thresh = 0x40;
+               }
+
+       } else {
+               if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
+                       cur_cck_cca_thresh = 0x83;
+               else
+                       cur_cck_cca_thresh = 0x40;
+       }
+
+       if (dm_digtable.cur_cck_cca_thres != cur_cck_cca_thresh) {
+               rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
+       }
+
+       dm_digtable.pre_cck_cca_thres = dm_digtable.cur_cck_cca_thres;
+       dm_digtable.cur_cck_cca_thres = cur_cck_cca_thresh;
+       RT_TRACE(COMP_DIG, DBG_TRACE,
+                ("CCK cca thresh hold =%x\n", dm_digtable.cur_cck_cca_thres));
+
+}
+
+void rtl8821ae_dm_dynamic_edcca(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       bool b_fw_current_in_ps_mode = false;
+
+       rtlpriv->cfg->ops->get_hw_reg(hw,HW_VAR_FW_PSMODE_STATUS, \
+               (u8*)(&b_fw_current_in_ps_mode));
+       if (b_fw_current_in_ps_mode)
+               return;
+}
+
+void rtl8812ae_dm_update_txpath(struct ieee80211_hw *hw, u8 path)
+{
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtldm->resp_tx_path != path) {
+               RT_TRACE(COMP_DIG, DBG_LOUD, \
+                       ("Need to Update Tx Path\n"));
+               if (path == RF90_PATH_A) {
+                       /*Tx by Reg*/
+                       rtl_set_bbreg(hw, 0x80c, 0xFFF0, 0x111);
+                        /*Resp Tx by Txinfo*/
+                       rtl_set_bbreg(hw, 0x6d8, BIT(7) | BIT(6), 1);
+               } else {
+                       /*Tx by Reg*/
+                       rtl_set_bbreg(hw, 0x80c, 0xFFF0, 0x222);
+                        /*Resp Tx by Txinfo*/
+                       rtl_set_bbreg(hw, 0x6d8, BIT(7) |BIT(6), 2);
+               }
+       }
+       rtldm->resp_tx_path = path;
+       RT_TRACE(COMP_DIG, DBG_LOUD, \
+               ("Path=%s\n",(path == RF90_PATH_A) ?  \
+               "RF90_PATH_A":"RF90_PATH_A"));
+}
+
+void rtl8812ae_dm_path_diversity_init(struct ieee80211_hw *hw)
+{
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+
+       //rtl_set_bbreg(hw, 0x80c , BIT(29), 1); /*Tx path from Reg*/
+       rtl_set_bbreg(hw, 0x80c , 0xFFF0, 0x111); /*Tx by Reg*/
+       rtl_set_bbreg(hw, 0x6d8 , BIT(7) | BIT(6), 1); /*Resp Tx by Txinfo*/
+       rtl8812ae_dm_update_txpath(hw, RF90_PATH_A);
+
+       rtldm->path_sel = 1; /* TxInfo default at path-A*/
+}
+
+void rtl812ae_dm_set_txpath_by_txinfo(struct ieee80211_hw *hw,
+       u8 *pdesc)
+{
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+
+       SET_TX_DESC_TX_ANT(pdesc, rtldm->path_sel);
+}
+
+void rtl8812ae_dm_path_statistics(struct ieee80211_hw *hw,
+       u32 rssi_a, u32 rssi_b)
+{
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+
+       rtldm->patha_sum += rssi_a;
+       rtldm->patha_cnt ++;
+
+       rtldm->pathb_sum += rssi_b;
+       rtldm->pathb_cnt ++;
+}
+
+void rtl8812ae_dm_path_diversity(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       u32     rssi_avg_a = 0;
+       u32 rssi_avg_b = 0;
+       u32 local_min_rssi = 0;
+       u32 min_rssi = 0xFF;
+       u8 tx_resp_path=0, target_path;
+       struct ieee80211_sta *sta = NULL;
+
+       sta = rtl_find_sta(hw, mac->bssid);
+       if (sta) {
+               /*Caculate RSSI per Path*/
+               rssi_avg_a = (rtldm->patha_cnt != 0) ? \
+                       (rtldm->patha_sum / rtldm->patha_cnt) : 0;
+               rssi_avg_b = (rtldm->pathb_cnt != 0) ? \
+                       (rtldm->pathb_sum / rtldm->pathb_cnt) : 0;
+
+               target_path = (rssi_avg_a == rssi_avg_b) ? rtldm->resp_tx_path : \
+                       ((rssi_avg_a>=rssi_avg_b) ? RF90_PATH_A : RF90_PATH_B);
+
+               RT_TRACE(COMP_DIG, DBG_TRACE, \
+                       ("assoc_id=%d, PathA_Sum=%d, PathA_Cnt=%d\n", \
+                       mac->assoc_id, rtldm->patha_sum, rtldm->patha_cnt));
+               RT_TRACE(COMP_DIG, DBG_TRACE, \
+                       ("assoc_id=%d, PathB_Sum=%d, PathB_Cnt=%d\n", \
+                       mac->assoc_id, rtldm->pathb_sum, rtldm->pathb_cnt));
+               RT_TRACE(COMP_DIG, DBG_TRACE, \
+                       ("assoc_id=%d, RssiAvgA= %d, RssiAvgB= %d\n", \
+                       mac->assoc_id, rssi_avg_a, rssi_avg_b));
+
+               /*Select Resp Tx Path*/
+               local_min_rssi = (rssi_avg_a > rssi_avg_b) ?  rssi_avg_b : rssi_avg_a;
+               if(local_min_rssi  < min_rssi)
+               {
+                       min_rssi = local_min_rssi;
+                       tx_resp_path = target_path;
+               }
+
+               /*Select Tx DESC*/
+               if(target_path == RF90_PATH_A)
+                       rtldm->path_sel = 1;
+               else
+                       rtldm->path_sel = 2;
+
+               RT_TRACE(COMP_DIG, DBG_TRACE, \
+                       ("Tx from TxInfo, TargetPath=%s\n", \
+                       (target_path==RF90_PATH_A) ? \
+                       "ODM_RF_PATH_A":"ODM_RF_PATH_B"));
+               RT_TRACE(COMP_DIG, DBG_TRACE, \
+                       ("pDM_PathDiv->PathSel= %d\n", \
+                       rtldm->path_sel));
+       }
+       rtldm->patha_cnt = 0;
+       rtldm->patha_sum = 0;
+       rtldm->pathb_cnt = 0;
+       rtldm->pathb_sum = 0;
+}
+
+void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       u8 crystal_cap;
+       u32 packet_count;
+       int cfo_khz_a,cfo_khz_b,cfo_ave = 0, adjust_xtal = 0;
+       int cfo_ave_diff;
+
+       if (rtlpriv->mac80211.link_state < MAC80211_LINKED){
+               /*1.Enable ATC*/
+               if (rtldm->atc_status == ATC_STATUS_OFF)
+               {
+                       rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON);
+                       rtldm->atc_status = ATC_STATUS_ON;
+               }
+
+               RT_TRACE(COMP_DIG, DBG_LOUD, \
+                       ("rtl8821ae_dm_dynamic_atc_switch(): No link!!\n"));
+               RT_TRACE(COMP_DIG, DBG_LOUD, \
+                       ("rtl8821ae_dm_dynamic_atc_switch(): atc_status = %d\n", \
+                       rtldm->atc_status));
+
+               if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap)
+               {
+                       rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
+                       crystal_cap = rtldm->crystal_cap & 0x3f;
+                       crystal_cap = crystal_cap & 0x3f;
+                       rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, \
+                               0x7ff80000, (crystal_cap | (crystal_cap << 6)));
+               }
+               RT_TRACE(COMP_DIG, DBG_LOUD, \
+                       ("rtl8821ae_dm_dynamic_atc_switch(): crystal_cap = 0x%x\n", \
+                       rtldm->crystal_cap));
+       }else{
+               /*1. Calculate CFO for path-A & path-B*/
+               cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
+               cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
+               packet_count = rtldm->packet_count;
+
+               /*2.No new packet*/
+               if (packet_count == rtldm->packet_count_pre) {
+                       RT_TRACE(COMP_DIG, DBG_LOUD, \
+                               ("rtl8821ae_dm_dynamic_atc_switch(): packet counter doesn't change\n"));
+                       return;
+               }
+
+               rtldm->packet_count_pre = packet_count;
+               RT_TRACE(COMP_DIG, DBG_LOUD, \
+                       ("rtl8821ae_dm_dynamic_atc_switch(): packet counter = %d\n", \
+                       rtldm->packet_count));
+
+               /*3.Average CFO*/
+               if (rtlpriv->phy.rf_type == RF_1T1R)
+                       cfo_ave = cfo_khz_a;
+               else
+                       cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1;
+
+               RT_TRACE(COMP_DIG, DBG_LOUD, \
+                       ("rtl8821ae_dm_dynamic_atc_switch():"
+                       "cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n",
+                       cfo_khz_a, cfo_khz_b, cfo_ave));
+
+               /*4.Avoid abnormal large CFO*/
+               cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave)?
+                                               (rtldm->cfo_ave_pre - cfo_ave):
+                                               (cfo_ave - rtldm->cfo_ave_pre);
+
+               if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0){
+                       RT_TRACE(COMP_DIG, DBG_LOUD, \
+                               ("rtl8821ae_dm_dynamic_atc_switch(): first large CFO hit\n"));
+                       rtldm->large_cfo_hit = 1;
+                       return;
+               }
+               else
+                       rtldm->large_cfo_hit = 0;
+
+               rtldm->cfo_ave_pre = cfo_ave;
+
+               /*CFO tracking by adjusting Xtal cap.*/
+
+               /*1.Dynamic Xtal threshold*/
+               if (cfo_ave >= -rtldm->cfo_threshold &&
+                       cfo_ave <= rtldm->cfo_threshold &&
+                       rtldm->is_freeze == 0){
+                       if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL){
+                               rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
+                               rtldm->is_freeze = 1;
+                       }
+                       else
+                               rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
+               }
+               RT_TRACE(COMP_DIG, DBG_LOUD, \
+                       ("rtl8821ae_dm_dynamic_atc_switch(): Dynamic threshold = %d\n", \
+                       rtldm->cfo_threshold));
+
+               /* 2.Calculate Xtal offset*/
+               if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
+                       adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
+               else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && rtlpriv->dm.crystal_cap > 0)
+                       adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
+               RT_TRACE(COMP_DIG, DBG_LOUD, \
+                       ("rtl8821ae_dm_dynamic_atc_switch(): "
+                       "Crystal cap = 0x%x, Crystal cap offset = %d\n",
+                       rtldm->crystal_cap, adjust_xtal));
+
+               /*3.Adjudt Crystal Cap.*/
+               if (adjust_xtal != 0){
+                       rtldm->is_freeze = 0;
+                       rtldm->crystal_cap += adjust_xtal;
+
+                       if (rtldm->crystal_cap > 0x3f)
+                               rtldm->crystal_cap = 0x3f;
+                       else if (rtldm->crystal_cap < 0)
+                               rtldm->crystal_cap = 0;
+
+                       crystal_cap = rtldm->crystal_cap & 0x3f;
+                       crystal_cap = crystal_cap & 0x3f;
+                       rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, \
+                               0x7ff80000, (crystal_cap | (crystal_cap << 6)));
+                       RT_TRACE(COMP_DIG, DBG_LOUD, \
+                               ("rtl8821ae_dm_dynamic_atc_switch(): New crystal cap = 0x%x \n", \
+                               rtldm->crystal_cap));
+               }
+       }
+
+}
+
+void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool b_fw_current_inpsmode = false;
+       bool b_fw_ps_awake = true;
+
+       rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+                                     (u8 *) (&b_fw_current_inpsmode));
+
+       rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
+                                     (u8 *) (&b_fw_ps_awake));
+
+       if(ppsc->p2p_ps_info.p2p_ps_mode)
+               b_fw_ps_awake = false;
+
+       if((ppsc->rfpwr_state == ERFON) &&
+               ((!b_fw_current_inpsmode) && b_fw_ps_awake) &&
+               (!ppsc->rfchange_inprogress)) {
+               rtl8821ae_dm_common_info_self_update(hw);
+               rtl8821ae_dm_false_alarm_counter_statistics(hw);
+               rtl8821ae_dm_check_rssi_monitor(hw);
+               rtl8821ae_dm_dig(hw);
+               rtl8821ae_dm_dynamic_edcca(hw);
+               rtl8821ae_dm_cck_packet_detection_thresh(hw);
+               rtl8821ae_dm_refresh_rate_adaptive_mask(hw);
+               rtl8821ae_dm_check_edca_turbo(hw);
+               rtl8821ae_dm_dynamic_atc_switch(hw);
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                       rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw);
+               else
+                       rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw);
+               rtl8821ae_dm_iq_calibrate(hw);
+               if (rtlpriv->cfg->ops->get_btc_status()){
+                       rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv);
+               }
+       }
+
+       rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
+}
+
+void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
+                                                                                                  u8 *pdesc, u32 mac_id)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       struct fast_ant_trainning *pfat_table= &(rtldm->fat_table);
+
+       if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE)
+               return;
+
+       if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
+               (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)){
+               SET_TX_DESC_TX_ANT(pdesc, pfat_table->antsel_a[mac_id]);
+       }
+}
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/dm.h b/drivers/staging/rtl8821ae/rtl8821ae/dm.h
new file mode 100644 (file)
index 0000000..ebbff9b
--- /dev/null
@@ -0,0 +1,426 @@
+/******************************************************************************
+ *
+ * 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        __RTL8821AE_DM_H__
+#define __RTL8821AE_DM_H__
+
+#define        MAIN_ANT        0
+#define        AUX_ANT 1
+#define        MAIN_ANT_CG_TRX 1
+#define        AUX_ANT_CG_TRX  0
+#define        MAIN_ANT_CGCS_RX        0
+#define        AUX_ANT_CGCS_RX 1
+
+#define        TXSCALE_TABLE_SIZE 37
+
+/*RF REG LIST*/
+#define        DM_REG_RF_MODE_11N                              0x00
+#define        DM_REG_RF_0B_11N                                0x0B
+#define        DM_REG_CHNBW_11N                                0x18
+#define        DM_REG_T_METER_11N                              0x24
+#define        DM_REG_RF_25_11N                                0x25
+#define        DM_REG_RF_26_11N                                0x26
+#define        DM_REG_RF_27_11N                                0x27
+#define        DM_REG_RF_2B_11N                                0x2B
+#define        DM_REG_RF_2C_11N                                0x2C
+#define        DM_REG_RXRF_A3_11N                              0x3C
+#define        DM_REG_T_METER_92D_11N                  0x42
+#define        DM_REG_T_METER_88E_11N                  0x42
+
+
+
+/*BB REG LIST*/
+/*PAGE 8 */
+#define        DM_REG_BB_CTRL_11N                              0x800
+#define        DM_REG_RF_PIN_11N                               0x804
+#define        DM_REG_PSD_CTRL_11N                             0x808
+#define        DM_REG_TX_ANT_CTRL_11N                  0x80C
+#define        DM_REG_BB_PWR_SAV5_11N                  0x818
+#define        DM_REG_CCK_RPT_FORMAT_11N               0x824
+#define        DM_REG_RX_DEFUALT_A_11N         0x858
+#define        DM_REG_RX_DEFUALT_B_11N         0x85A
+#define        DM_REG_BB_PWR_SAV3_11N                  0x85C
+#define        DM_REG_ANTSEL_CTRL_11N                  0x860
+#define        DM_REG_RX_ANT_CTRL_11N                  0x864
+#define        DM_REG_PIN_CTRL_11N                             0x870
+#define        DM_REG_BB_PWR_SAV1_11N                  0x874
+#define        DM_REG_ANTSEL_PATH_11N                  0x878
+#define        DM_REG_BB_3WIRE_11N                     0x88C
+#define        DM_REG_SC_CNT_11N                               0x8C4
+#define        DM_REG_PSD_DATA_11N                     0x8B4
+/*PAGE 9*/
+#define        DM_REG_ANT_MAPPING1_11N         0x914
+#define        DM_REG_ANT_MAPPING2_11N         0x918
+/*PAGE A*/
+#define        DM_REG_CCK_ANTDIV_PARA1_11N     0xA00
+#define        DM_REG_CCK_CCA_11N                      0xA0A
+#define        DM_REG_CCK_CCA_11AC                     0xA0A
+#define        DM_REG_CCK_ANTDIV_PARA2_11N     0xA0C
+#define        DM_REG_CCK_ANTDIV_PARA3_11N     0xA10
+#define        DM_REG_CCK_ANTDIV_PARA4_11N     0xA14
+#define        DM_REG_CCK_FILTER_PARA1_11N     0xA22
+#define        DM_REG_CCK_FILTER_PARA2_11N     0xA23
+#define        DM_REG_CCK_FILTER_PARA3_11N     0xA24
+#define        DM_REG_CCK_FILTER_PARA4_11N     0xA25
+#define        DM_REG_CCK_FILTER_PARA5_11N     0xA26
+#define        DM_REG_CCK_FILTER_PARA6_11N     0xA27
+#define        DM_REG_CCK_FILTER_PARA7_11N     0xA28
+#define        DM_REG_CCK_FILTER_PARA8_11N     0xA29
+#define        DM_REG_CCK_FA_RST_11N                   0xA2C
+#define        DM_REG_CCK_FA_MSB_11N                   0xA58
+#define        DM_REG_CCK_FA_LSB_11N                   0xA5C
+#define        DM_REG_CCK_CCA_CNT_11N                  0xA60
+#define        DM_REG_BB_PWR_SAV4_11N                  0xA74
+/*PAGE B */
+#define        DM_REG_LNA_SWITCH_11N                   0xB2C
+#define        DM_REG_PATH_SWITCH_11N                  0xB30
+#define        DM_REG_RSSI_CTRL_11N                    0xB38
+#define        DM_REG_CONFIG_ANTA_11N                  0xB68
+#define        DM_REG_RSSI_BT_11N                              0xB9C
+/*PAGE C */
+#define        DM_REG_OFDM_FA_HOLDC_11N                0xC00
+#define        DM_REG_RX_PATH_11N                              0xC04
+#define        DM_REG_TRMUX_11N                                0xC08
+#define        DM_REG_OFDM_FA_RSTC_11N         0xC0C
+#define        DM_REG_RXIQI_MATRIX_11N         0xC14
+#define        DM_REG_TXIQK_MATRIX_LSB1_11N    0xC4C
+#define        DM_REG_IGI_A_11N                                0xC50
+#define        DM_REG_IGI_A_11AC                               0xC50
+#define        DM_REG_ANTDIV_PARA2_11N         0xC54
+#define        DM_REG_IGI_B_11N                                        0xC58
+#define        DM_REG_IGI_B_11AC                                       0xE50
+#define        DM_REG_ANTDIV_PARA3_11N         0xC5C
+#define        DM_REG_BB_PWR_SAV2_11N                  0xC70
+#define        DM_REG_RX_OFF_11N                               0xC7C
+#define        DM_REG_TXIQK_MATRIXA_11N                0xC80
+#define        DM_REG_TXIQK_MATRIXB_11N                0xC88
+#define        DM_REG_TXIQK_MATRIXA_LSB2_11N   0xC94
+#define        DM_REG_TXIQK_MATRIXB_LSB2_11N   0xC9C
+#define        DM_REG_RXIQK_MATRIX_LSB_11N     0xCA0
+#define        DM_REG_ANTDIV_PARA1_11N         0xCA4
+#define        DM_REG_OFDM_FA_TYPE1_11N                0xCF0
+/*PAGE D */
+#define        DM_REG_OFDM_FA_RSTD_11N         0xD00
+#define        DM_REG_OFDM_FA_TYPE2_11N                0xDA0
+#define        DM_REG_OFDM_FA_TYPE3_11N                0xDA4
+#define        DM_REG_OFDM_FA_TYPE4_11N                0xDA8
+/*PAGE E */
+#define        DM_REG_TXAGC_A_6_18_11N         0xE00
+#define        DM_REG_TXAGC_A_24_54_11N                0xE04
+#define        DM_REG_TXAGC_A_1_MCS32_11N      0xE08
+#define        DM_REG_TXAGC_A_MCS0_3_11N               0xE10
+#define        DM_REG_TXAGC_A_MCS4_7_11N               0xE14
+#define        DM_REG_TXAGC_A_MCS8_11_11N      0xE18
+#define        DM_REG_TXAGC_A_MCS12_15_11N     0xE1C
+#define        DM_REG_FPGA0_IQK_11N                    0xE28
+#define        DM_REG_TXIQK_TONE_A_11N         0xE30
+#define        DM_REG_RXIQK_TONE_A_11N         0xE34
+#define        DM_REG_TXIQK_PI_A_11N                   0xE38
+#define        DM_REG_RXIQK_PI_A_11N                   0xE3C
+#define        DM_REG_TXIQK_11N                                0xE40
+#define        DM_REG_RXIQK_11N                                0xE44
+#define        DM_REG_IQK_AGC_PTS_11N                  0xE48
+#define        DM_REG_IQK_AGC_RSP_11N                  0xE4C
+#define        DM_REG_BLUETOOTH_11N                    0xE6C
+#define        DM_REG_RX_WAIT_CCA_11N                  0xE70
+#define        DM_REG_TX_CCK_RFON_11N                  0xE74
+#define        DM_REG_TX_CCK_BBON_11N                  0xE78
+#define        DM_REG_OFDM_RFON_11N                    0xE7C
+#define        DM_REG_OFDM_BBON_11N                    0xE80
+#define DM_REG_TX2RX_11N                               0xE84
+#define        DM_REG_TX2TX_11N                                0xE88
+#define        DM_REG_RX_CCK_11N                               0xE8C
+#define        DM_REG_RX_OFDM_11N                              0xED0
+#define        DM_REG_RX_WAIT_RIFS_11N         0xED4
+#define        DM_REG_RX2RX_11N                                0xED8
+#define        DM_REG_STANDBY_11N                              0xEDC
+#define        DM_REG_SLEEP_11N                                0xEE0
+#define        DM_REG_PMPD_ANAEN_11N                   0xEEC
+
+
+/*MAC REG LIST*/
+#define        DM_REG_BB_RST_11N                               0x02
+#define        DM_REG_ANTSEL_PIN_11N                   0x4C
+#define        DM_REG_EARLY_MODE_11N                   0x4D0
+#define        DM_REG_RSSI_MONITOR_11N         0x4FE
+#define        DM_REG_EDCA_VO_11N                              0x500
+#define        DM_REG_EDCA_VI_11N                              0x504
+#define        DM_REG_EDCA_BE_11N                              0x508
+#define        DM_REG_EDCA_BK_11N                              0x50C
+#define        DM_REG_TXPAUSE_11N                              0x522
+#define        DM_REG_RESP_TX_11N                              0x6D8
+#define        DM_REG_ANT_TRAIN_PARA1_11N      0x7b0
+#define        DM_REG_ANT_TRAIN_PARA2_11N      0x7b4
+
+
+/*DIG Related*/
+#define        DM_BIT_IGI_11N                                  0x0000007F
+#define        DM_BIT_IGI_11AC                                 0xFFFFFFFF
+
+
+
+#define HAL_DM_DIG_DISABLE                     BIT(0)
+#define HAL_DM_HIPWR_DISABLE           BIT(1)
+
+#define OFDM_TABLE_LENGTH                      43
+#define CCK_TABLE_LENGTH                       33
+
+#define OFDM_TABLE_SIZE                        37
+#define CCK_TABLE_SIZE                         33
+
+#define BW_AUTO_SWITCH_HIGH_LOW                25
+#define BW_AUTO_SWITCH_LOW_HIGH                30
+
+#define DM_DIG_THRESH_HIGH                     40
+#define DM_DIG_THRESH_LOW                      35
+
+#define DM_FALSEALARM_THRESH_LOW       400
+#define DM_FALSEALARM_THRESH_HIGH      1000
+
+#define DM_DIG_MAX                                     0x3e
+#define DM_DIG_MIN                                     0x1e
+
+#define DM_DIG_MAX_AP                          0x32
+#define DM_DIG_MIN_AP                          0x20
+
+#define DM_DIG_FA_UPPER                                0x3e
+#define DM_DIG_FA_LOWER                                0x1e
+#define DM_DIG_FA_TH0                          0x200
+#define DM_DIG_FA_TH1                          0x300
+#define DM_DIG_FA_TH2                          0x400
+
+#define DM_DIG_BACKOFF_MAX                     12
+#define DM_DIG_BACKOFF_MIN                     -4
+#define DM_DIG_BACKOFF_DEFAULT         10
+
+#define RXPATHSELECTION_SS_TH_lOW      30
+#define RXPATHSELECTION_DIFF_TH                18
+
+#define DM_RATR_STA_INIT                       0
+#define DM_RATR_STA_HIGH                       1
+#define DM_RATR_STA_MIDDLE                     2
+#define DM_RATR_STA_LOW                                3
+
+#define CTS2SELF_THVAL                         30
+#define REGC38_TH                                      20
+
+#define WAIOTTHVal                                     25
+
+#define TXHIGHPWRLEVEL_NORMAL          0
+#define TXHIGHPWRLEVEL_LEVEL1          1
+#define TXHIGHPWRLEVEL_LEVEL2          2
+#define TXHIGHPWRLEVEL_BT1                     3
+#define TXHIGHPWRLEVEL_BT2                     4
+
+#define DM_TYPE_BYFW                           0
+#define DM_TYPE_BYDRIVER                       1
+
+#define TX_POWER_NEAR_FIELD_THRESH_LVL2        74
+#define TX_POWER_NEAR_FIELD_THRESH_LVL1        67
+#define TXPWRTRACK_MAX_IDX 6
+
+/* Dynamic ATC switch */
+#define ATC_STATUS_OFF                         0x0                     /* enable */
+#define        ATC_STATUS_ON                           0x1                     /* disable */
+#define        CFO_THRESHOLD_XTAL                      10                      /* kHz */
+#define        CFO_THRESHOLD_ATC                       80                      /* kHz */
+
+#define AVG_THERMAL_NUM_8812A  4
+#define TXPWR_TRACK_TABLE_SIZE         30
+#define MAX_PATH_NUM_8812A             2
+#define MAX_PATH_NUM_8821A             1
+
+
+struct ps_t {
+       u8 pre_ccastate;
+       u8 cur_ccasate;
+       u8 pre_rfstate;
+       u8 cur_rfstate;
+       u8 initialize;
+       long rssi_val_min;
+
+};
+
+struct dig_t {
+       u8 dig_enable_flag;
+       u8 dig_ext_port_stage;
+       u32 rssi_lowthresh;
+       u32 rssi_highthresh;
+
+       u32 fa_lowthresh;
+       u32 fa_highthresh;
+
+       u8 cursta_connectctate;
+       u8 presta_connectstate;
+       u8 curmultista_connectstate;
+
+       u8 pre_igvalue;
+       u8 cur_igvalue;
+       u8 bt30_cur_igi;
+       u8 backup_igvalue;
+       u8 stop_dig;
+
+       char backoff_val;
+       char backoff_val_range_max;
+       char backoff_val_range_min;
+       u8 rx_gain_range_max;
+       u8 rx_gain_range_min;
+       u8 rssi_val_min;
+
+       u8 pre_cck_cca_thres;
+       u8 cur_cck_cca_thres;
+       u8 pre_cck_pd_state;
+       u8 cur_cck_pd_state;
+
+       u8 large_fa_hit;
+       u8 forbidden_igi;
+       u32 recover_cnt;
+
+       u8 dig_dynamic_min_0;
+       u8 dig_dynamic_min_1;
+       bool b_media_connect_0;
+       bool b_media_connect_1;
+
+       u32 antdiv_rssi_max;
+       u32 rssi_max;
+};
+
+
+enum FAT_STATE {
+       FAT_NORMAL_STATE        = 0,
+       FAT_TRAINING_STATE = 1,
+};
+
+enum tag_dynamic_init_gain_operation_type_definition {
+       DIG_TYPE_THRESH_HIGH = 0,
+       DIG_TYPE_THRESH_LOW = 1,
+       DIG_TYPE_BACKOFF = 2,
+       DIG_TYPE_RX_GAIN_MIN = 3,
+       DIG_TYPE_RX_GAIN_MAX = 4,
+       DIG_TYPE_ENABLE = 5,
+       DIG_TYPE_DISABLE = 6,
+       DIG_OP_TYPE_MAX
+};
+
+enum tag_cck_packet_detection_threshold_type_definition {
+       CCK_PD_STAGE_LowRssi = 0,
+       CCK_PD_STAGE_HighRssi = 1,
+       CCK_FA_STAGE_Low = 2,
+       CCK_FA_STAGE_High = 3,
+       CCK_PD_STAGE_MAX = 4,
+};
+
+enum dm_1r_cca_e {
+       CCA_1R = 0,
+       CCA_2R = 1,
+       CCA_MAX = 2,
+};
+
+enum dm_rf_e {
+       RF_SAVE = 0,
+       RF_NORMAL = 1,
+       RF_MAX = 2,
+};
+
+enum dm_sw_ant_switch_e {
+       ANS_ANTENNA_B = 1,
+       ANS_ANTENNA_A = 2,
+       ANS_ANTENNA_MAX = 3,
+};
+
+enum dm_dig_ext_port_alg_e {
+       DIG_EXT_PORT_STAGE_0 = 0,
+       DIG_EXT_PORT_STAGE_1 = 1,
+       DIG_EXT_PORT_STAGE_2 = 2,
+       DIG_EXT_PORT_STAGE_3 = 3,
+       DIG_EXT_PORT_STAGE_MAX = 4,
+};
+
+enum dm_dig_connect_e {
+       DIG_STA_DISCONNECT = 0,
+       DIG_STA_CONNECT = 1,
+       DIG_STA_BEFORE_CONNECT = 2,
+       DIG_MULTISTA_DISCONNECT = 3,
+       DIG_MULTISTA_CONNECT = 4,
+       DIG_CONNECT_MAX
+};
+
+enum pwr_track_control_method {
+       BBSWING,
+       TXAGC,
+       MIX_MODE
+};
+
+#define BT_RSSI_STATE_NORMAL_POWER      BIT_OFFSET_LEN_MASK_32(0, 1)
+#define BT_RSSI_STATE_AMDPU_OFF         BIT_OFFSET_LEN_MASK_32(1, 1)
+#define BT_RSSI_STATE_SPECIAL_LOW       BIT_OFFSET_LEN_MASK_32(2, 1)
+#define BT_RSSI_STATE_BG_EDCA_LOW       BIT_OFFSET_LEN_MASK_32(3, 1)
+#define BT_RSSI_STATE_TXPOWER_LOW       BIT_OFFSET_LEN_MASK_32(4, 1)
+#define GET_UNDECORATED_AVERAGE_RSSI(_priv)     \
+        (((struct rtl_priv *)(_priv))->mac80211.opmode == NL80211_IFTYPE_ADHOC)?  \
+        (((struct rtl_priv *)(_priv))->dm.entry_min_undecoratedsmoothed_pwdb):  \
+        (((struct rtl_priv *)(_priv))->dm.undecorated_smoothed_pwdb)
+
+extern struct dig_t dm_digtable;
+void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
+                                                                                                  u8 *pdesc, u32 mac_id);
+void rtl8821ae_dm_ant_sel_statistics(struct ieee80211_hw *hw,
+                                                                                         u8 antsel_tr_mux, u32 mac_id,
+                                                                                         u32 rx_pwdb_all);
+void rtl8821ae_dm_fast_antenna_trainning_callback(unsigned long data);
+void rtl8821ae_dm_init(struct ieee80211_hw *hw);
+void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw);
+void rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi);
+void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw);
+void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw);
+void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
+void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw,
+                                                                                                  u8 type,u8 *pdirection,
+                                                                                                  u32 *poutwrite_val);
+void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw);
+void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca);
+void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(struct ieee80211_hw *hw);
+void rtl8812ae_dm_path_diversity(struct ieee80211_hw *hw);
+void rtl8812ae_dm_path_diversity_init(struct ieee80211_hw *hw);
+void rtl8812ae_dm_path_statistics(struct ieee80211_hw *hw,
+       u32 rssi_a, u32 rssi_b);
+void rtl812ae_dm_set_txpath_by_txinfo(struct ieee80211_hw *hw,
+       u8 *pdesc);
+void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
+                                                                                               enum pwr_track_control_method method,
+                                                                                               u8 rf_path,
+                                                                                               u8 channel_mapped_index);
+void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
+       enum pwr_track_control_method method, u8 rf_path, u8 channel_mapped_index);
+
+void rtl8812ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate);
+u8 rtl8812ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate);
+void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw *hw);
+void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw *hw);
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/fw.c b/drivers/staging/rtl8821ae/rtl8821ae/fw.c
new file mode 100644 (file)
index 0000000..4083cab
--- /dev/null
@@ -0,0 +1,1349 @@
+/******************************************************************************
+ *
+ * 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 "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "fw.h"
+#include "dm.h"
+
+static void _rtl8821ae_enable_fw_download(struct ieee80211_hw *hw, bool enable)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp;
+
+       if (enable) {
+               rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05);
+
+               tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
+               rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
+
+               tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
+               //printk("0x80=%02x.\n",tmp);
+       } else {
+               tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
+               rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
+               tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
+               //printk("0x80=%02x.\n",tmp);
+       }
+
+}
+
+static void _rtl8821ae_fw_block_write(struct ieee80211_hw *hw,
+                                  const u8 *buffer, u32 size)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 blockSize = sizeof(u32);
+       u8 *bufferPtr = (u8 *) buffer;
+       u32 *pu4BytePtr = (u32 *) buffer;
+       u32 i, offset, blockCount, remainSize;
+
+       blockCount = size / blockSize;
+       remainSize = size % blockSize;
+
+       for (i = 0; i < blockCount; i++) {
+               offset = i * blockSize;
+               rtl_write_dword(rtlpriv, (FW_8821AE_START_ADDRESS + offset),
+                               *(pu4BytePtr + i));
+       }
+
+       if (remainSize) {
+               offset = blockCount * blockSize;
+               bufferPtr += offset;
+               for (i = 0; i < remainSize; i++) {
+                       rtl_write_byte(rtlpriv, (FW_8821AE_START_ADDRESS +
+                                                offset + i), *(bufferPtr + i));
+               }
+       }
+}
+
+static void _rtl8821ae_fw_page_write(struct ieee80211_hw *hw,
+                                 u32 page, const u8 *buffer, u32 size)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 value8;
+       u8 u8page = (u8) (page & 0x07);
+
+       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
+
+       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
+       _rtl8821ae_fw_block_write(hw, buffer, size);
+}
+
+static void _rtl8821ae_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
+{
+       u32 fwlen = *pfwlen;
+       u8 remain = (u8) (fwlen % 4);
+
+       remain = (remain == 0) ? 0 : (4 - remain);
+
+       while (remain > 0) {
+               pfwbuf[fwlen] = 0;
+               fwlen++;
+               remain--;
+       }
+
+       *pfwlen = fwlen;
+}
+
+static void _rtl8821ae_write_fw(struct ieee80211_hw *hw,
+                                                                 enum version_8821ae version,
+                                                                 u8 *buffer, u32 size)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 *bufferPtr = (u8 *) buffer;
+       u32 pageNums, remainSize;
+       u32 page, offset;
+
+       RT_TRACE(COMP_FW, DBG_LOUD, ("FW size is %d bytes,\n", size));
+
+       _rtl8821ae_fill_dummy(bufferPtr, &size);
+
+       pageNums = size / FW_8821AE_PAGE_SIZE;
+       remainSize = size % FW_8821AE_PAGE_SIZE;
+
+       if (pageNums > 8) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Page numbers should not greater then 8\n"));
+       }
+
+       for (page = 0; page < pageNums; page++) {
+               offset = page * FW_8821AE_PAGE_SIZE;
+               _rtl8821ae_fw_page_write(hw, page, (bufferPtr + offset),
+                                     FW_8821AE_PAGE_SIZE);
+       }
+
+       if (remainSize) {
+               offset = pageNums * FW_8821AE_PAGE_SIZE;
+               page = pageNums;
+               _rtl8821ae_fw_page_write(hw, page, (bufferPtr + offset),
+                                     remainSize);
+       }
+
+}
+
+static int _rtl8821ae_fw_free_to_go(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int err = -EIO;
+       u32 counter = 0;
+       u32 value32;
+
+       do {
+               value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+       } while ((counter++ < FW_8821AE_POLLING_TIMEOUT_COUNT) &&
+                (!(value32 & FWDL_CHKSUM_RPT)));
+
+       if (counter >= FW_8821AE_POLLING_TIMEOUT_COUNT) {
+               RT_TRACE(COMP_ERR, DBG_LOUD,
+                        ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
+                         value32));
+               goto exit;
+       }
+
+       RT_TRACE(COMP_FW, DBG_EMERG,
+                ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
+
+       value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+       value32 |= MCUFWDL_RDY;
+       value32 &= ~WINTINI_RDY;
+       rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
+
+       rtl8821ae_firmware_selfreset(hw);
+
+       counter = 0;
+       do {
+               value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+               if (value32 & WINTINI_RDY) {
+                       RT_TRACE(COMP_FW, DBG_LOUD,
+                                ("Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",
+                                 value32));
+                       err = 0;
+                       goto exit;
+               }
+
+               udelay(FW_8821AE_POLLING_DELAY);
+
+       } while (counter++ < FW_8821AE_POLLING_TIMEOUT_COUNT);
+
+       RT_TRACE(COMP_ERR, DBG_EMERG,
+                ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
+
+exit:
+       return err;
+}
+
+int rtl8821ae_download_fw(struct ieee80211_hw *hw,
+       bool buse_wake_on_wlan_fw
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl8821a_firmware_header *pfwheader;
+       u8 *pfwdata;
+       u32 fwsize;
+       int err;
+       enum version_8821ae version = rtlhal->version;
+
+       if(!rtlhal->pfirmware)
+               return 1;
+
+       pfwheader = (struct rtl8821a_firmware_header *)rtlhal->pfirmware;
+       pfwdata = (u8 *) rtlhal->pfirmware;
+       fwsize = rtlhal->fwsize;
+       RT_TRACE(COMP_FW, DBG_DMESG,
+                ("normal Firmware SIZE %d \n",fwsize));
+
+       if (IS_FW_HEADER_EXIST_8812(pfwheader) || IS_FW_HEADER_EXIST_8821(pfwheader)) {
+               RT_TRACE(COMP_FW, DBG_DMESG,
+                        ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
+                         pfwheader->version, pfwheader->signature,
+                         (int)sizeof(struct rtl8821a_firmware_header)));
+
+               pfwdata = pfwdata + sizeof(struct rtl8821a_firmware_header);
+               fwsize = fwsize - sizeof(struct rtl8821a_firmware_header);
+       }
+
+       if(rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)){
+               rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
+               rtl8821ae_firmware_selfreset(hw);
+       }
+       _rtl8821ae_enable_fw_download(hw, true);
+       _rtl8821ae_write_fw(hw, version, pfwdata, fwsize);
+       _rtl8821ae_enable_fw_download(hw, false);
+
+       err = _rtl8821ae_fw_free_to_go(hw);
+       if (err) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Firmware is not ready to run!\n"));
+       } else {
+               RT_TRACE(COMP_FW, DBG_LOUD,
+                        ("Firmware is ready to run!\n"));
+       }
+
+       return 0;
+}
+
+static bool _rtl8821ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 val_hmetfr;
+       bool result = false;
+
+       val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
+       if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
+               result = true;
+       return result;
+}
+
+static void _rtl8821ae_fill_h2c_command(struct ieee80211_hw *hw,
+                             u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 boxnum =0;
+       u16 box_reg = 0, box_extreg = 0;
+       u8 u1b_tmp = 0;
+       bool isfw_read = false;
+       u8 buf_index = 0;
+       bool bwrite_sucess = false;
+       u8 wait_h2c_limmit = 100;
+       /*u8 wait_writeh2c_limmit = 100;*/
+       u8 boxcontent[4], boxextcontent[4];
+       u32 h2c_waitcounter = 0;
+       unsigned long flag =0;
+       u8 idx =0;
+
+       RT_TRACE(COMP_CMD, DBG_LOUD, ("come in\n"));
+
+       while (true) {
+               spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+               if (rtlhal->b_h2c_setinprogress) {
+                       RT_TRACE(COMP_CMD, DBG_LOUD,
+                                ("H2C set in progress! Wait to set.."
+                                 "element_id(%d).\n", element_id));
+
+                       while (rtlhal->b_h2c_setinprogress) {
+                               spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
+                                                      flag);
+                               h2c_waitcounter++;
+                               RT_TRACE(COMP_CMD, DBG_LOUD,
+                                        ("Wait 100 us (%d times)...\n",
+                                         h2c_waitcounter));
+                               udelay(100);
+
+                               if (h2c_waitcounter > 1000)
+                                       return;
+                               spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
+                                                 flag);
+                       }
+                       spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+               } else {
+                       rtlhal->b_h2c_setinprogress = true;
+                       spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+                       break;
+               }
+       }
+
+       while (!bwrite_sucess) {
+       /*cosa remove this because never reach this.*/
+#if 0
+               wait_writeh2c_limmit--;
+               if (wait_writeh2c_limmit == 0) {
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                                ("Write H2C fail because no trigger "
+                                 "for FW INT!\n"));
+                       break;
+               }
+#endif
+
+               boxnum = rtlhal->last_hmeboxnum;
+               switch (boxnum) {
+               case 0:
+                       box_reg = REG_HMEBOX_0;
+                       box_extreg = REG_HMEBOX_EXT_0;
+                       break;
+               case 1:
+                       box_reg = REG_HMEBOX_1;
+                       box_extreg = REG_HMEBOX_EXT_1;
+                       break;
+               case 2:
+                       box_reg = REG_HMEBOX_2;
+                       box_extreg = REG_HMEBOX_EXT_2;
+                       break;
+               case 3:
+                       box_reg = REG_HMEBOX_3;
+                       box_extreg = REG_HMEBOX_EXT_3;
+                       break;
+               default:
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                                ("switch case not process \n"));
+                       break;
+               }
+
+               isfw_read = false;
+               u1b_tmp = rtl_read_byte(rtlpriv, REG_CR);
+
+               if (u1b_tmp != 0xEA)
+                       isfw_read = true;
+               else {
+                       if( rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xEA ||
+                               rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xEA)
+                               rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xFF);
+               }
+
+               if (isfw_read == true) {
+                       wait_h2c_limmit = 100;
+                       isfw_read = _rtl8821ae_check_fw_read_last_h2c(hw, boxnum);
+                       while (!isfw_read) {
+                               /*wait until Fw read*/
+                               wait_h2c_limmit--;
+                               if (wait_h2c_limmit == 0) {
+                                       RT_TRACE(COMP_CMD, DBG_LOUD,
+                                                ("Wating too long for FW read "
+                                                 "clear HMEBox(%d)!\n", boxnum));
+                                       break;
+                               }
+
+                               udelay(10);
+
+                               isfw_read = _rtl8821ae_check_fw_read_last_h2c(hw, boxnum);
+                               u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
+                               RT_TRACE(COMP_CMD, DBG_LOUD,
+                                        ("Wating for FW read clear HMEBox(%d)!!! "
+                                         "0x130 = %2x\n", boxnum, u1b_tmp));
+                       }
+               }
+
+               if (!isfw_read) {
+                       RT_TRACE(COMP_CMD, DBG_LOUD,
+                                ("Write H2C register BOX[%d] fail!!!!! "
+                                 "Fw do not read. \n", boxnum));
+                       break;
+               }
+
+               memset(boxcontent, 0, sizeof(boxcontent));
+               memset(boxextcontent, 0, sizeof(boxextcontent));
+               boxcontent[0] = element_id;
+               RT_TRACE(COMP_CMD, DBG_LOUD,
+                        ("Write element_id box_reg(%4x) = %2x \n",
+                         box_reg, element_id));
+
+               switch (cmd_len) {
+               case 1:
+               case 2:
+               case 3:
+                       /*boxcontent[0] &= ~(BIT(7));*/
+                       memcpy((u8 *) (boxcontent) + 1,
+                              p_cmdbuffer + buf_index, cmd_len);
+
+                       for (idx = 0; idx < 4; idx++) {
+                               rtl_write_byte(rtlpriv, box_reg + idx,
+                                              boxcontent[idx]);
+                       }
+                       break;
+               case 4:
+               case 5:
+               case 6:
+               case 7:
+                       /*boxcontent[0] |= (BIT(7));*/
+                       memcpy((u8 *) (boxextcontent),
+                              p_cmdbuffer + buf_index+3, cmd_len-3);
+                       memcpy((u8 *) (boxcontent) + 1,
+                              p_cmdbuffer + buf_index, 3);
+
+                       for (idx = 0; idx < 4; idx++) {
+                               rtl_write_byte(rtlpriv, box_extreg + idx,
+                                              boxextcontent[idx]);
+                       }
+
+                       for (idx = 0; idx < 4; idx++) {
+                               rtl_write_byte(rtlpriv, box_reg + idx,
+                                              boxcontent[idx]);
+                       }
+                       break;
+               default:
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                                ("switch case not process \n"));
+                       break;
+               }
+
+               bwrite_sucess = true;
+
+               rtlhal->last_hmeboxnum = boxnum + 1;
+               if (rtlhal->last_hmeboxnum == 4)
+                       rtlhal->last_hmeboxnum = 0;
+
+               RT_TRACE(COMP_CMD, DBG_LOUD,
+                        ("pHalData->last_hmeboxnum  = %d\n",
+                         rtlhal->last_hmeboxnum));
+       }
+
+       spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+       rtlhal->b_h2c_setinprogress = false;
+       spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+
+       RT_TRACE(COMP_CMD, DBG_LOUD, ("go out\n"));
+}
+
+void rtl8821ae_fill_h2c_cmd(struct ieee80211_hw *hw,
+                        u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
+{
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 tmp_cmdbuf[2];
+
+       if (rtlhal->bfw_ready == false) {
+               RT_ASSERT(false, ("return H2C cmd because of Fw "
+                                 "download fail!!!\n"));
+               return;
+       }
+
+       memset(tmp_cmdbuf, 0, 8);
+       memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
+       _rtl8821ae_fill_h2c_command(hw, element_id, cmd_len, (u8 *) & tmp_cmdbuf);
+
+       return;
+}
+
+void rtl8821ae_firmware_selfreset(struct ieee80211_hw *hw)
+{
+       u8 u1b_tmp;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+       {
+               u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
+               rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(3))));
+       }else {
+               u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
+               rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(0))));
+       }
+
+       u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2))));
+       udelay(50);
+
+       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+       {
+               u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
+               rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp | BIT(3)));
+       }else {
+               u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
+               rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp | BIT(0)));
+       }
+
+       u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2)));
+
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("  _8051Reset8812ae(): 8051 reset success .\n"));
+
+}
+
+void rtl8821ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 u1_h2c_set_pwrmode[H2C_8821AE_PWEMODE_LENGTH] = { 0 };
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       u8 rlbm,power_state = 0;
+       RT_TRACE(COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
+
+       SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
+       rlbm = 0;/*YJ,temp,120316. FW now not support RLBM=2.*/
+       SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
+       SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
+       SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, ppsc->reg_max_lps_awakeintvl);
+       SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
+       if(mode == FW_PS_ACTIVE_MODE)
+       {
+               power_state |= FW_PWR_STATE_ACTIVE;
+       }
+       else
+       {
+               power_state |= FW_PWR_STATE_RF_OFF;
+       }
+       SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
+
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+                     "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode \n",
+                     u1_h2c_set_pwrmode, H2C_8821AE_PWEMODE_LENGTH);
+       rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_SETPWRMODE, H2C_8821AE_PWEMODE_LENGTH, u1_h2c_set_pwrmode);
+
+}
+
+void rtl8821ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
+{
+       u8 u1_joinbssrpt_parm[1] = { 0 };
+
+       SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
+
+       rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_JOINBSSRPT, 1, u1_joinbssrpt_parm);
+}
+
+void rtl8821ae_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,  u8 ap_offload_enable)
+{
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       u8 u1_apoffload_parm[H2C_8821AE_AP_OFFLOAD_LENGTH] = { 0 };
+
+       SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable);
+       SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->bhiddenssid);
+       SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0);
+
+       rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_AP_OFFLOAD, H2C_8821AE_AP_OFFLOAD_LENGTH, u1_apoffload_parm);
+
+}
+
+static bool _rtl8821ae_cmd_send_packet(struct ieee80211_hw *hw,
+                               struct sk_buff *skb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring;
+       struct rtl_tx_desc *pdesc;
+       u8 own;
+       unsigned long flags;
+       struct sk_buff *pskb = NULL;
+
+       ring = &rtlpci->tx_ring[BEACON_QUEUE];
+
+       pskb = __skb_dequeue(&ring->queue);
+       if (pskb)
+               kfree_skb(pskb);
+
+       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+       pdesc = &ring->desc[0];
+       own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
+
+       rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
+
+       __skb_queue_tail(&ring->queue, skb);
+
+       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+       rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
+
+       return true;
+}
+
+#define BEACON_PG              0 /* ->1 */
+#define PSPOLL_PG              2
+#define NULL_PG                        3
+#define PROBERSP_PG            4 /* ->5 */
+
+#define BEACON_PG_8812         0
+#define PSPOLL_PG_8812         1
+#define NULL_PG_8812                   2
+#define PROBERSP_PG_8812               3
+
+#define BEACON_PG_8821         0
+#define PSPOLL_PG_8821         1
+#define NULL_PG_8821                   2
+#define PROBERSP_PG_8821               3
+
+#define TOTAL_RESERVED_PKT_LEN_8812    2048
+#define TOTAL_RESERVED_PKT_LEN_8821    1024
+
+
+static u8 reserved_page_packet_8821[TOTAL_RESERVED_PKT_LEN_8821] = {
+       /* page 0 */
+       0x80, 0x00, 0x00, 0x00,  0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0x00, 0xe0,  0x4c, 0x02, 0xe2, 0x64,
+       0x40, 0x16, 0x9f, 0x23,  0xd4, 0x46, 0x20, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x64, 0x00, 0x20, 0x04,  0x00, 0x06, 0x64, 0x6c,
+       0x69, 0x6e, 0x6b, 0x31,  0x01, 0x08, 0x82, 0x84,
+       0x8b, 0x96, 0x0c, 0x18,  0x30, 0x48, 0x03, 0x01,
+       0x0b, 0x06, 0x02, 0x00,  0x00, 0x2a, 0x01, 0x8b,
+       0x32, 0x04, 0x12, 0x24,  0x60, 0x6c, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x10, 0x00, 0x28, 0x8c,  0x00, 0x12, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x81, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       /* page 1 */
+       0xa4, 0x10, 0x01, 0xc0,  0x40, 0x16, 0x9f, 0x23,
+       0xd4, 0x46, 0x00, 0xe0,  0x4c, 0x02, 0xe2, 0x64,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x18, 0x00, 0x28, 0x8c,  0x00, 0x12, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x80, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       /* page 2 */
+       0x48, 0x01, 0x00, 0x00,  0x40, 0x16, 0x9f, 0x23,
+       0xd4, 0x46, 0x00, 0xe0,  0x4c, 0x02, 0xe2, 0x64,
+       0x40, 0x16, 0x9f, 0x23,  0xd4, 0x46, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x1a, 0x00, 0x28, 0x8c,  0x00, 0x12, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x80, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       /* page 3 */
+       0xc8, 0x01, 0x00, 0x00,  0x40, 0x16, 0x9f, 0x23,
+       0xd4, 0x46, 0x00, 0xe0,  0x4c, 0x02, 0xe2, 0x64,
+       0x40, 0x16, 0x9f, 0x23,  0xd4, 0x46, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+};
+
+
+static u8 reserved_page_packet_8812[TOTAL_RESERVED_PKT_LEN_8812] = {
+       0x80, 0x00, 0x00, 0x00,  0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0x00, 0xE0,  0x4C, 0x02, 0x53, 0xE5,
+       0xE0, 0x46, 0x9A, 0x57,  0x71, 0x30, 0x20, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x64, 0x00, 0x30, 0x04,  0x00, 0x0C, 0x4E, 0x45,
+       0x54, 0x47, 0x45, 0x41,  0x52, 0x5F, 0x31, 0x35,
+       0x30, 0x4E, 0x01, 0x08,  0x82, 0x84, 0x8B, 0x96,
+       0x0C, 0x12, 0x18, 0x24,  0x03, 0x01, 0x03, 0x06,
+       0x02, 0x00, 0x00, 0x2A,  0x01, 0x8A, 0x32, 0x04,
+       0x30, 0x48, 0x60, 0x6C,  0xDD, 0x18, 0x00, 0x50,
+       0xF2, 0x01, 0x01, 0x00,  0x00, 0x50, 0xF2, 0x02,
+       0x01, 0x00, 0x00, 0x50,  0xF2, 0x02, 0x01, 0x00,
+       0x00, 0x50, 0xF2, 0x02,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x10, 0x00, 0x28, 0x8C,  0x00, 0x12, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x81, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+
+       0xA4, 0x10, 0x02, 0xC0,  0xE0, 0x46, 0x9A, 0x57,
+       0x71, 0x30, 0x00, 0xE0,  0x4C, 0x02, 0x53, 0xE5,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x18, 0x00, 0x28, 0x8C,  0x00, 0x12, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x01, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x80, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+
+       0x48, 0x01, 0x00, 0x00,  0xE0, 0x46, 0x9A, 0x57,
+       0x71, 0x30, 0x00, 0xE0,  0x4C, 0x02, 0x53, 0xE5,
+       0xE0, 0x46, 0x9A, 0x57,  0x71, 0x30, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x1A, 0x00, 0x28, 0x8C,  0x00, 0x12, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x01, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x80, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+
+       0xC8, 0x01, 0x00, 0x00,  0xE0, 0x46, 0x9A, 0x57,
+       0x71, 0x30, 0x00, 0xE0,  0x4C, 0x02, 0x53, 0xE5,
+       0xE0, 0x46, 0x9A, 0x57,  0x71, 0x30, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+};
+
+void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct sk_buff *skb = NULL;
+
+       u32 totalpacketlen;
+       bool rtstatus;
+       u8 u1RsvdPageLoc[5] = { 0 };
+       bool b_dlok = false;
+
+       u8* beacon;
+       u8* p_pspoll;
+       u8* nullfunc;
+       u8* p_probersp;
+       /*---------------------------------------------------------
+                               (1) beacon
+       ---------------------------------------------------------*/
+       beacon = &reserved_page_packet_8812[BEACON_PG_8812 * 512];
+       SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
+
+       /*-------------------------------------------------------
+                               (2) ps-poll
+       --------------------------------------------------------*/
+       p_pspoll = &reserved_page_packet_8812[PSPOLL_PG_8812 * 512];
+       SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
+       SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
+       SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
+
+       SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG_8812);
+
+       /*--------------------------------------------------------
+                               (3) null data
+       ---------------------------------------------------------*/
+       nullfunc = &reserved_page_packet_8812[NULL_PG_8812* 512];
+       SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
+       SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
+
+       SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG_8812);
+
+       /*---------------------------------------------------------
+                               (4) probe response
+       ----------------------------------------------------------*/
+       p_probersp = &reserved_page_packet_8812[PROBERSP_PG_8812 * 512];
+       SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
+       SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
+
+       SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG_8812);
+
+       totalpacketlen = TOTAL_RESERVED_PKT_LEN_8812;
+
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+                     "rtl8821ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL \n",
+                     &reserved_page_packet_8812[0], totalpacketlen);
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+                     "rtl8821ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL \n",
+                     u1RsvdPageLoc, 3);
+
+
+       skb = dev_alloc_skb(totalpacketlen);
+       memcpy((u8 *) skb_put(skb, totalpacketlen),
+              &reserved_page_packet_8812, totalpacketlen);
+
+       rtstatus = _rtl8821ae_cmd_send_packet(hw, skb);
+
+       if (rtstatus)
+               b_dlok = true;
+
+       if (b_dlok) {
+               RT_TRACE(COMP_POWER, DBG_LOUD,
+                        ("Set RSVD page location to Fw.\n"));
+               RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+                               "H2C_RSVDPAGE:\n",
+                               u1RsvdPageLoc, 3);
+               rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_RSVDPAGE,
+                                   sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
+       } else
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
+}
+
+void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct sk_buff *skb = NULL;
+
+       u32 totalpacketlen;
+       bool rtstatus;
+       u8 u1RsvdPageLoc[5] = { 0 };
+       bool b_dlok = false;
+
+       u8* beacon;
+       u8* p_pspoll;
+       u8* nullfunc;
+       u8* p_probersp;
+       /*---------------------------------------------------------
+                               (1) beacon
+       ---------------------------------------------------------*/
+       beacon = &reserved_page_packet_8821[BEACON_PG_8821 * 256];
+       SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
+
+       /*-------------------------------------------------------
+                               (2) ps-poll
+       --------------------------------------------------------*/
+       p_pspoll = &reserved_page_packet_8821[PSPOLL_PG_8821 * 256];
+       SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
+       SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
+       SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
+
+       SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG_8821);
+
+       /*--------------------------------------------------------
+                               (3) null data
+       ---------------------------------------------------------*/
+       nullfunc = &reserved_page_packet_8821[NULL_PG_8821 * 256];
+       SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
+       SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
+
+       SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG_8821);
+
+       /*---------------------------------------------------------
+                               (4) probe response
+       ----------------------------------------------------------*/
+       p_probersp = &reserved_page_packet_8821[PROBERSP_PG_8821 * 256];
+       SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
+       SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
+
+       SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG_8821);
+
+       totalpacketlen = TOTAL_RESERVED_PKT_LEN_8821;
+
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+                     "rtl8821ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL \n",
+                     &reserved_page_packet_8821[0], totalpacketlen);
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+                     "rtl8821ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL \n",
+                     u1RsvdPageLoc, 3);
+
+
+       skb = dev_alloc_skb(totalpacketlen);
+       memcpy((u8 *) skb_put(skb, totalpacketlen),
+              &reserved_page_packet_8821, totalpacketlen);
+
+       rtstatus = _rtl8821ae_cmd_send_packet(hw, skb);
+
+       if (rtstatus)
+               b_dlok = true;
+
+       if (b_dlok) {
+               RT_TRACE(COMP_POWER, DBG_LOUD,
+                        ("Set RSVD page location to Fw.\n"));
+               RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+                               "H2C_RSVDPAGE:\n",
+                               u1RsvdPageLoc, 3);
+               rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_RSVDPAGE,
+                                   sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
+       } else
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
+}
+
+/*Shoud check FW support p2p or not.*/
+void rtl8821ae_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
+{
+       u8 u1_ctwindow_period[1] ={ ctwindow};
+
+       rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
+
+}
+
+void rtl8821ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
+       struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
+       u8      i;
+       u16     ctwindow;
+       u32     start_time, tsf_low;
+
+       switch(p2p_ps_state)
+       {
+               case P2P_PS_DISABLE:
+                       RT_TRACE(COMP_FW, DBG_LOUD,("P2P_PS_DISABLE \n"));
+                       memset(p2p_ps_offload, 0, 1);
+                       break;
+               case P2P_PS_ENABLE:
+                       RT_TRACE(COMP_FW, DBG_LOUD,("P2P_PS_ENABLE \n"));
+                       /* update CTWindow value. */
+                       if( p2pinfo->ctwindow > 0 )
+                       {
+                               p2p_ps_offload->CTWindow_En = 1;
+                               ctwindow = p2pinfo->ctwindow;
+                               rtl8821ae_set_p2p_ctw_period_cmd(hw, ctwindow);
+                       }
+
+                       /* hw only support 2 set of NoA */
+                       for( i=0 ; i<p2pinfo->noa_num ; i++)
+                       {
+                               /* To control the register setting for which NOA*/
+                               rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
+                               if(i == 0)
+                                       p2p_ps_offload->NoA0_En = 1;
+                               else
+                                       p2p_ps_offload->NoA1_En = 1;
+
+                               /* config P2P NoA Descriptor Register */
+                               rtl_write_dword(rtlpriv, 0x5E0, p2pinfo->noa_duration[i]);
+                               rtl_write_dword(rtlpriv, 0x5E4, p2pinfo->noa_interval[i]);
+
+                               /*Get Current \14TSF value */
+                               tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
+
+                               start_time = p2pinfo->noa_start_time[i];
+                               if(p2pinfo->noa_count_type[i] != 1)
+                               {
+                                       while( start_time <= (tsf_low+(50*1024) ) ) {
+                                               start_time += p2pinfo->noa_interval[i];
+                                               if(p2pinfo->noa_count_type[i] != 255)
+                                                       p2pinfo->noa_count_type[i]--;
+                                       }
+                               }
+                               rtl_write_dword(rtlpriv, 0x5E8, start_time);
+                               rtl_write_dword(rtlpriv, 0x5EC, p2pinfo->noa_count_type[i] );
+
+                       }
+
+                       if( (p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0) )
+                       {
+                               /* rst p2p circuit */
+                               rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
+
+                               p2p_ps_offload->Offload_En = 1;
+
+                               if(P2P_ROLE_GO == rtlpriv->mac80211.p2p)
+                               {
+                                       p2p_ps_offload->role= 1;
+                                       p2p_ps_offload->AllStaSleep = 0;
+                               }
+                               else
+                               {
+                                       p2p_ps_offload->role= 0;
+                               }
+
+                               p2p_ps_offload->discovery = 0;
+                       }
+                       break;
+               case P2P_PS_SCAN:
+                       RT_TRACE(COMP_FW, DBG_LOUD,("P2P_PS_SCAN \n"));
+                       p2p_ps_offload->discovery = 1;
+                       break;
+               case P2P_PS_SCAN_DONE:
+                       RT_TRACE(COMP_FW, DBG_LOUD,("P2P_PS_SCAN_DONE \n"));
+                       p2p_ps_offload->discovery = 0;
+                       p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
+                       break;
+               default:
+                       break;
+       }
+
+       rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
+
+}
+
+void rtl8812ae_c2h_ra_report_handler(
+       struct ieee80211_hw *hw,
+       u8 *cmd_buf,
+       u8 cmd_len
+)
+{
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 rate = cmd_buf[0] & 0x3F;
+
+       rtlhal->current_ra_rate= rtl8812ae_hw_rate_to_mrate(hw, rate);
+
+       rtl8812ae_dm_update_init_rate(hw, rate);
+}
+
+
+void _rtl8812ae_c2h_content_parsing(
+       struct ieee80211_hw *hw,
+       u8 c2h_cmd_id,
+       u8 c2h_cmd_len,
+       u8 *tmp_buf
+)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       switch (c2h_cmd_id) {
+       case C2H_8812_DBG:
+               RT_TRACE(COMP_FW, DBG_LOUD,("[C2H], C2H_8812_DBG!!\n"));
+               break;
+
+       case C2H_8812_RA_RPT:
+               rtl8812ae_c2h_ra_report_handler(hw, tmp_buf, c2h_cmd_len);
+               break;
+
+       default:
+               break;
+       }
+
+}
+
+void rtl8812ae_c2h_packet_handler(
+       struct ieee80211_hw *hw,
+       u8 *buffer,
+       u8 length
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 c2h_cmd_id=0, c2h_cmd_seq=0, c2h_cmd_len=0;
+       u8 *tmp_buf=NULL;
+
+       c2h_cmd_id = buffer[0];
+       c2h_cmd_seq = buffer[1];
+       c2h_cmd_len = length -2;
+       tmp_buf = buffer + 2;
+
+       RT_TRACE(COMP_FW, DBG_LOUD,
+               ("[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
+               c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len));
+
+       RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD,
+               "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
+       _rtl8812ae_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
+}
+
+
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/fw.h b/drivers/staging/rtl8821ae/rtl8821ae/fw.h
new file mode 100644 (file)
index 0000000..30eec88
--- /dev/null
@@ -0,0 +1,321 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE__FW__H__
+#define __RTL8821AE__FW__H__
+
+#define FW_8821AE_SIZE                                 0x8000
+#define FW_8821AE_START_ADDRESS                        0x1000
+#define FW_8821AE_END_ADDRESS                  0x5FFF
+#define FW_8821AE_PAGE_SIZE                            4096
+#define FW_8821AE_POLLING_DELAY                        5
+#define FW_8821AE_POLLING_TIMEOUT_COUNT        6000
+
+#define IS_FW_HEADER_EXIST_8812(_pfwhdr)       \
+       ((_pfwhdr->signature&0xFFF0) == 0x9500 )
+
+#define IS_FW_HEADER_EXIST_8821(_pfwhdr)       \
+       ((_pfwhdr->signature&0xFFF0) == 0x2100 )
+
+#define USE_OLD_WOWLAN_DEBUG_FW 0
+
+#define H2C_8821AE_RSVDPAGE_LOC_LEN            5
+#define H2C_8821AE_PWEMODE_LENGTH                      5
+#define H2C_8821AE_JOINBSSRPT_LENGTH           1
+#define H2C_8821AE_AP_OFFLOAD_LENGTH           3
+#define H2C_8821AE_WOWLAN_LENGTH                       3
+#define H2C_8821AE_KEEP_ALIVE_CTRL_LENGTH      3
+#if(USE_OLD_WOWLAN_DEBUG_FW == 0)
+#define H2C_8821AE_REMOTE_WAKE_CTRL_LEN        1
+#else
+#define H2C_8821AE_REMOTE_WAKE_CTRL_LEN        3
+#endif
+#define H2C_8821AE_AOAC_GLOBAL_INFO_LEN        2
+#define H2C_8821AE_AOAC_RSVDPAGE_LOC_LEN       7
+
+
+/* Fw PS state for RPWM.
+*BIT[2:0] = HW state
+*BIT[3] = Protocol PS state,   1: register active state , 0: register sleep state
+*BIT[4] = sub-state
+*/
+#define        FW_PS_GO_ON                     BIT(0)
+#define        FW_PS_TX_NULL                   BIT(1)
+#define        FW_PS_RF_ON                     BIT(2)
+#define        FW_PS_REGISTER_ACTIVE   BIT(3)
+
+#define        FW_PS_DPS               BIT(0)
+#define        FW_PS_LCLK              (FW_PS_DPS)
+#define        FW_PS_RF_OFF            BIT(1)
+#define        FW_PS_ALL_ON            BIT(2)
+#define        FW_PS_ST_ACTIVE         BIT(3)
+#define        FW_PS_ISR_ENABLE        BIT(4)
+#define        FW_PS_IMR_ENABLE        BIT(5)
+
+
+#define        FW_PS_ACK               BIT(6)
+#define        FW_PS_TOGGLE            BIT(7)
+
+ /* 8821AE RPWM value*/
+ /* BIT[0] = 1: 32k, 0: 40M*/
+#define        FW_PS_CLOCK_OFF         BIT(0)          /* 32k*/
+#define        FW_PS_CLOCK_ON          0               /*40M*/
+
+#define        FW_PS_STATE_MASK                (0x0F)
+#define        FW_PS_STATE_HW_MASK     (0x07)
+#define        FW_PS_STATE_INT_MASK    (0x3F)  /*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/
+
+#define        FW_PS_STATE(x)                  (FW_PS_STATE_MASK & (x))
+#define        FW_PS_STATE_HW(x)               (FW_PS_STATE_HW_MASK & (x))
+#define        FW_PS_STATE_INT(x)      (FW_PS_STATE_INT_MASK & (x))
+#define        FW_PS_ISR_VAL(x)                ((x) & 0x70)
+#define        FW_PS_IMR_MASK(x)       ((x) & 0xDF)
+#define        FW_PS_KEEP_IMR(x)               ((x) & 0x20)
+
+
+#define        FW_PS_STATE_S0          (FW_PS_DPS)
+#define        FW_PS_STATE_S1          (FW_PS_LCLK)
+#define        FW_PS_STATE_S2          (FW_PS_RF_OFF)
+#define        FW_PS_STATE_S3          (FW_PS_ALL_ON)
+#define        FW_PS_STATE_S4          ((FW_PS_ST_ACTIVE) | (FW_PS_ALL_ON))
+
+#define        FW_PS_STATE_ALL_ON_8821AE       (FW_PS_CLOCK_ON) /* ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))*/
+#define        FW_PS_STATE_RF_ON_8821AE        (FW_PS_CLOCK_ON) /* (FW_PS_RF_ON)*/
+#define        FW_PS_STATE_RF_OFF_8821AE       (FW_PS_CLOCK_ON) /* 0x0*/
+#define        FW_PS_STATE_RF_OFF_LOW_PWR_8821AE       (FW_PS_CLOCK_OFF) /* (FW_PS_STATE_RF_OFF)*/
+
+#define        FW_PS_STATE_ALL_ON_92C  (FW_PS_STATE_S4)
+#define        FW_PS_STATE_RF_ON_92C           (FW_PS_STATE_S3)
+#define        FW_PS_STATE_RF_OFF_92C  (FW_PS_STATE_S2)
+#define        FW_PS_STATE_RF_OFF_LOW_PWR_92C  (FW_PS_STATE_S1)
+
+
+/* For 8821AE H2C PwrMode Cmd ID 5.*/
+#define        FW_PWR_STATE_ACTIVE     ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
+#define        FW_PWR_STATE_RF_OFF     0
+
+#define        FW_PS_IS_ACK(x)                 ((x) & FW_PS_ACK )
+#define        FW_PS_IS_CLK_ON(x)              ((x) & (FW_PS_RF_OFF |FW_PS_ALL_ON ))
+#define        FW_PS_IS_RF_ON(x)               ((x) & (FW_PS_ALL_ON))
+#define        FW_PS_IS_ACTIVE(x)              ((x) & (FW_PS_ST_ACTIVE))
+#define        FW_PS_IS_CPWM_INT(x)    ((x) & 0x40)
+
+#define        FW_CLR_PS_STATE(x)              ((x) = ((x) & (0xF0)))
+
+#define        IS_IN_LOW_POWER_STATE_8821AE(FwPSState)         \
+                       (FW_PS_STATE(FwPSState) == FW_PS_CLOCK_OFF)
+
+#define        FW_PWR_STATE_ACTIVE     ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
+#define        FW_PWR_STATE_RF_OFF     0
+
+struct rtl8821a_firmware_header {
+       u16 signature;
+       u8 category;
+       u8 function;
+       u16 version;
+       u8 subversion;
+       u8 rsvd1;
+       u8 month;
+       u8 date;
+       u8 hour;
+       u8 minute;
+       u16 ramcodeSize;
+       u16 rsvd2;
+       u32 svnindex;
+       u32 rsvd3;
+       u32 rsvd4;
+       u32 rsvd5;
+};
+
+enum rtl8812_c2h_evt{
+       C2H_8812_DBG = 0,
+       C2H_8812_LB = 1,
+       C2H_8812_TXBF = 2,
+       C2H_8812_TX_REPORT = 3,
+       C2H_8812_BT_INFO = 9,
+       C2H_8812_BT_MP = 11,
+       C2H_8812_RA_RPT=12,
+
+       C2H_8812_FW_SWCHNL = 0x10,
+       C2H_8812_IQK_FINISH = 0x11,
+       MAX_8812_C2HEVENT
+};
+
+enum rtl8821a_h2c_cmd {
+       H2C_8821AE_RSVDPAGE = 0,
+       H2C_8821AE_JOINBSSRPT = 1,
+       H2C_8821AE_SCAN = 2,
+       H2C_8821AE_KEEP_ALIVE_CTRL = 3,
+       H2C_8821AE_DISCONNECT_DECISION = 4,
+#if(USE_OLD_WOWLAN_DEBUG_FW == 1)
+       H2C_8821AE_WO_WLAN = 5,
+#endif
+       H2C_8821AE_INIT_OFFLOAD = 6,
+#if(USE_OLD_WOWLAN_DEBUG_FW == 1)
+       H2C_8821AE_REMOTE_WAKE_CTRL = 7,
+#endif
+       H2C_8821AE_AP_OFFLOAD = 8,
+       H2C_8821AE_BCN_RSVDPAGE = 9,
+       H2C_8821AE_PROBERSP_RSVDPAGE = 10,
+
+       H2C_8821AE_SETPWRMODE = 0x20,
+       H2C_8821AE_PS_TUNING_PARA = 0x21,
+       H2C_8821AE_PS_TUNING_PARA2 = 0x22,
+       H2C_8821AE_PS_LPS_PARA = 0x23,
+       H2C_8821AE_P2P_PS_OFFLOAD = 024,
+
+#if(USE_OLD_WOWLAN_DEBUG_FW == 0)
+       H2C_8821AE_WO_WLAN = 0x80,
+       H2C_8821AE_REMOTE_WAKE_CTRL = 0x81,
+       H2C_8821AE_AOAC_GLOBAL_INFO = 0x82,
+       H2C_8821AE_AOAC_RSVDPAGE = 0x83,
+#endif
+       H2C_RSSI_REPORT = 0x42,
+       H2C_8821AE_RA_MASK = 0x40,
+       H2C_8821AE_SELECTIVE_SUSPEND_ROF_CMD,
+       H2C_8821AE_P2P_PS_MODE,
+       H2C_8821AE_PSD_RESULT,
+       /*Not defined CTW CMD for P2P yet*/
+       H2C_8821AE_P2P_PS_CTW_CMD,
+       MAX_8821AE_H2CCMD
+};
+
+#define pagenum_128(_len)              (u32)(((_len)>>7) + ((_len)&0x7F ? 1:0))
+
+#define SET_8821AE_H2CCMD_WOWLAN_FUNC_ENABLE(__pH2CCmd, __Value)               \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__pH2CCmd, __Value)              \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__pH2CCmd, __Value)          \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__pH2CCmd, __Value)                \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_ALL_PKT_DROP(__pH2CCmd, __Value)              \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_GPIO_ACTIVE(__pH2CCmd, __Value)                               \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_REKEY_WAKE_UP(__pH2CCmd, __Value)             \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 6, 1, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__pH2CCmd, __Value)                \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 7, 1, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_GPIONUM(__pH2CCmd, __Value)                                   \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value)
+#define SET_8821AE_H2CCMD_WOWLAN_GPIO_DURATION(__pH2CCmd, __Value)                     \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value)
+
+
+#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val)                 \
+       SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value)               \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value)
+#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value)   \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value)
+#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__pH2CCmd, __Value)     \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value)
+#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value)            \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value)
+#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value)  \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value)
+#define GET_8821AE_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd)         \
+       LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8)
+
+#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val)            \
+       SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val)            \
+       SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val)               \
+       SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val)            \
+       SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
+
+/* AP_OFFLOAD */
+#define SET_H2CCMD_AP_OFFLOAD_ON(__pH2CCmd, __Value)   \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
+#define SET_H2CCMD_AP_OFFLOAD_HIDDEN(__pH2CCmd, __Value)               \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value)
+#define SET_H2CCMD_AP_OFFLOAD_DENYANY(__pH2CCmd, __Value)      \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value)
+#define SET_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__pH2CCmd, __Value)               \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value)
+
+/* Keep Alive Control*/
+#define SET_8821AE_H2CCMD_KEEP_ALIVE_ENABLE(__pH2CCmd, __Value)                                \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
+#define SET_8821AE_H2CCMD_KEEP_ALIVE_ACCPEPT_USER_DEFINED(__pH2CCmd, __Value)  \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
+#define SET_8821AE_H2CCMD_KEEP_ALIVE_PERIOD(__pH2CCmd, __Value)                                \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value)
+
+/*REMOTE_WAKE_CTRL */
+#define SET_8821AE_H2CCMD_REMOTE_WAKE_CTRL_EN(__pH2CCmd, __Value)                              \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
+#if(USE_OLD_WOWLAN_DEBUG_FW == 0)
+#define SET_8821AE_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__pH2CCmd, __Value)                          \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
+#define SET_8821AE_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__pH2CCmd, __Value)                          \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
+#define SET_8821AE_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__pH2CCmd, __Value)                          \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
+#else
+#define SET_8821AE_H2CCMD_REMOTE_WAKE_CTRL_PAIRWISE_ENC_ALG(__pH2CCmd, __Value)                \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value)
+#define SET_8821AE_H2CCMD_REMOTE_WAKE_CTRL_GROUP_ENC_ALG(__pH2CCmd, __Value)           \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value)
+#endif
+
+/* GTK_OFFLOAD */
+#define SET_8821AE_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__pH2CCmd, __Value)                \
+       SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
+#define SET_8821AE_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__pH2CCmd, __Value)           \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value)
+
+/* AOAC_RSVDPAGE_LOC */
+#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(__pH2CCmd, __Value)          \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd), 0, 8, __Value)
+#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__pH2CCmd, __Value)                \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value)
+#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__pH2CCmd, __Value)           \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value)
+#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__pH2CCmd, __Value)                \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value)
+#define SET_8821AE_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__pH2CCmd, __Value)                       \
+       SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value)
+
+int rtl8821ae_download_fw(struct ieee80211_hw *hw,
+                               bool buse_wake_on_wlan_fw);
+void rtl8821ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
+                        u32 cmd_len, u8 *p_cmdbuffer);
+void rtl8821ae_firmware_selfreset(struct ieee80211_hw *hw);
+void rtl8821ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
+void rtl8821ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
+void rtl8821ae_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,  u8 ap_offload_enable);
+void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
+void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
+void rtl8821ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
+void rtl8812ae_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 length);
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/hal_bt_coexist.c b/drivers/staging/rtl8821ae/rtl8821ae/hal_bt_coexist.c
new file mode 100644 (file)
index 0000000..8bee772
--- /dev/null
@@ -0,0 +1,519 @@
+/******************************************************************************
+ *
+ * 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 "hal_bt_coexist.h"
+#include "../pci.h"
+#include "dm.h"
+#include "fw.h"
+#include "phy.h"
+#include "reg.h"
+#include "hal_btc.h"
+
+static bool bt_operation_on = false;
+
+void rtl8821ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, bool b_reject)
+{
+#if 0
+       struct rtl_priv rtlpriv = rtl_priv(hw);
+       PRX_TS_RECORD                   pRxTs = NULL;
+
+       if(b_reject){
+               // Do not allow receiving A-MPDU aggregation.
+               if (rtlpriv->mac80211.vendor == PEER_CISCO) {
+                               if (pHTInfo->bAcceptAddbaReq) {
+                                       RTPRINT(FBT, BT_TRACE, ("BT_Disallow AMPDU \n"));
+                                       pHTInfo->bAcceptAddbaReq = FALSE;
+                                       if(GetTs(Adapter, (PTS_COMMON_INFO*)(&pRxTs), pMgntInfo->Bssid, 0, RX_DIR, FALSE))
+                                               TsInitDelBA(Adapter, (PTS_COMMON_INFO)pRxTs, RX_DIR);
+                               }
+                       } else {
+                               if (!pHTInfo->bAcceptAddbaReq) {
+                                       RTPRINT(FBT, BT_TRACE, ("BT_Allow AMPDU BT Idle\n"));
+                                       pHTInfo->bAcceptAddbaReq = TRUE;
+                               }
+                       }
+               } else {
+                       if(rtlpriv->mac80211.vendor == PEER_CISCO) {
+                               if (!pHTInfo->bAcceptAddbaReq) {
+                                       RTPRINT(FBT, BT_TRACE, ("BT_Allow AMPDU \n"));
+                                       pHTInfo->bAcceptAddbaReq = TRUE;
+                               }
+                       }
+               }
+#endif
+}
+
+void _rtl8821ae_dm_bt_check_wifi_state(struct ieee80211_hw *hw)
+{
+struct rtl_priv *rtlpriv = rtl_priv(hw);
+struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+if (rtlpriv->link_info.b_busytraffic) {
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_IDLE;
+
+       if(rtlpriv->link_info.b_tx_busy_traffic) {
+               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_UPLINK;
+       } else {
+               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_UPLINK;
+       }
+
+       if(rtlpriv->link_info.b_rx_busy_traffic) {
+               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_DOWNLINK;
+       } else {
+               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_DOWNLINK;
+       }
+} else {
+       rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_IDLE;
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_UPLINK;
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_DOWNLINK;
+}
+
+if (rtlpriv->mac80211.mode == WIRELESS_MODE_G
+       || rtlpriv->mac80211.mode == WIRELESS_MODE_B) {
+       rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_LEGACY;
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_HT20;
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_HT40;
+} else {
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_LEGACY;
+       if(rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_HT40;
+               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_HT20;
+       } else {
+               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_HT20;
+               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_HT40;
+       }
+}
+
+if (bt_operation_on) {
+       rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_BT30;
+} else {
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_BT30;
+}
+}
+
+
+u8 rtl8821ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
+                                               u8      level_num, u8   rssi_thresh, u8 rssi_thresh1)
+
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       long undecoratedsmoothed_pwdb = 0;
+       u8 bt_rssi_state = 0;
+
+       undecoratedsmoothed_pwdb =  rtl8821ae_dm_bt_get_rx_ss(hw);
+
+       if(level_num == 2) {
+               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
+
+               if( (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_LOW) ||
+                       (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_STAY_LOW)) {
+                       if(undecoratedsmoothed_pwdb >= (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
+                               bt_rssi_state = BT_RSSI_STATE_HIGH;
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_RSSI_1_HIGH;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state switch to High\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n"));
+                       }
+               } else {
+                       if(undecoratedsmoothed_pwdb < rssi_thresh) {
+                               bt_rssi_state = BT_RSSI_STATE_LOW;
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_RSSI_1_LOW;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state stay at High\n"));
+                       }
+               }
+       } else if(level_num == 3) {
+               if(rssi_thresh > rssi_thresh1) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 thresh error!!\n"));
+                       return rtlpcipriv->btcoexist.bt_pre_rssi_state;
+               }
+
+               if( (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_LOW) ||
+                       (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_STAY_LOW)) {
+                       if(undecoratedsmoothed_pwdb >= (rssi_thresh+BT_FW_COEX_THRESH_TOL)) {
+                               bt_rssi_state = BT_RSSI_STATE_MEDIUM;
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n"));
+                       }
+               } else if( (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_MEDIUM) ||
+                       (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_STAY_MEDIUM)) {
+                       if(undecoratedsmoothed_pwdb >= (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
+                               bt_rssi_state = BT_RSSI_STATE_HIGH;
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_RSSI_1_HIGH;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state switch to High\n"));
+                       } else if(undecoratedsmoothed_pwdb < rssi_thresh) {
+                               bt_rssi_state = BT_RSSI_STATE_LOW;
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_RSSI_1_LOW;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state stay at Medium\n"));
+                       }
+               } else {
+                       if(undecoratedsmoothed_pwdb < rssi_thresh1) {
+                               bt_rssi_state = BT_RSSI_STATE_MEDIUM;
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
+                               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,("[DM][BT], RSSI_1 state switch to Medium\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[DM][BT], RSSI_1 state stay at High\n"));
+                       }
+               }
+       }
+
+       rtlpcipriv->btcoexist.bt_pre_rssi_state1 = bt_rssi_state;
+
+       return bt_rssi_state;
+}
+
+u8 rtl8821ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
+                                               u8      level_num, u8   rssi_thresh, u8 rssi_thresh1)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       long undecoratedsmoothed_pwdb = 0;
+       u8 bt_rssi_state = 0;
+
+       undecoratedsmoothed_pwdb = rtl8821ae_dm_bt_get_rx_ss(hw);
+
+       if (level_num == 2) {
+               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
+
+               if ((rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_LOW) ||
+                       (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_STAY_LOW)){
+                       if (undecoratedsmoothed_pwdb
+                               >= (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
+                               bt_rssi_state = BT_RSSI_STATE_HIGH;
+                               rtlpcipriv->btcoexist.current_state
+                                       |= BT_COEX_STATE_WIFI_RSSI_HIGH;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state switch to High\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state stay at Low\n"));
+                       }
+               } else {
+                       if (undecoratedsmoothed_pwdb < rssi_thresh) {
+                               bt_rssi_state = BT_RSSI_STATE_LOW;
+                               rtlpcipriv->btcoexist.current_state
+                                       |= BT_COEX_STATE_WIFI_RSSI_LOW;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state switch to Low\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state stay at High\n"));
+                       }
+               }
+       }
+       else if (level_num == 3) {
+               if (rssi_thresh > rssi_thresh1) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                               ("[DM][BT], RSSI thresh error!!\n"));
+                       return rtlpcipriv->btcoexist.bt_pre_rssi_state;
+               }
+               if ((rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_LOW) ||
+                       (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_STAY_LOW)) {
+                       if(undecoratedsmoothed_pwdb
+                               >= (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
+                               bt_rssi_state = BT_RSSI_STATE_MEDIUM;
+                               rtlpcipriv->btcoexist.current_state
+                                       |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state switch to Medium\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state stay at Low\n"));
+                       }
+               } else if ((rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_MEDIUM) ||
+                       (rtlpcipriv->btcoexist.bt_pre_rssi_state == BT_RSSI_STATE_STAY_MEDIUM)) {
+                       if (undecoratedsmoothed_pwdb
+                               >= (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
+                               bt_rssi_state = BT_RSSI_STATE_HIGH;
+                               rtlpcipriv->btcoexist.current_state
+                                       |= BT_COEX_STATE_WIFI_RSSI_HIGH;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state switch to High\n"));
+                       } else if(undecoratedsmoothed_pwdb < rssi_thresh)
+                       {
+                               bt_rssi_state = BT_RSSI_STATE_LOW;
+                               rtlpcipriv->btcoexist.current_state
+                                       |= BT_COEX_STATE_WIFI_RSSI_LOW;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state switch to Low\n"));
+                       } else {
+                               bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state stay at Medium\n"));
+                       }
+               } else {
+                       if(undecoratedsmoothed_pwdb < rssi_thresh1) {
+                               bt_rssi_state = BT_RSSI_STATE_MEDIUM;
+                               rtlpcipriv->btcoexist.current_state
+                                       |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
+                               rtlpcipriv->btcoexist.current_state
+                                       &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                                       ("[DM][BT], RSSI state switch to Medium\n"));
+                       } else {
+                       bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                               ("[DM][BT], RSSI state stay at High\n"));
+                       }
+               }
+       }
+
+       rtlpcipriv->btcoexist.bt_pre_rssi_state = bt_rssi_state;
+       return bt_rssi_state;
+}
+long rtl8821ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       long undecoratedsmoothed_pwdb = 0;
+
+       if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
+               undecoratedsmoothed_pwdb = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
+       } else {
+               undecoratedsmoothed_pwdb
+                       = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+       }
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("rtl8821ae_dm_bt_get_rx_ss() = %ld\n", undecoratedsmoothed_pwdb));
+
+       return undecoratedsmoothed_pwdb;
+}
+
+void rtl8821ae_dm_bt_balance(struct ieee80211_hw *hw,
+                                                       bool b_balance_on, u8 ms0, u8 ms1)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 h2c_parameter[3] ={0};
+
+       if (b_balance_on) {
+               h2c_parameter[2] = 1;
+               h2c_parameter[1] = ms1;
+               h2c_parameter[0] = ms0;
+               rtlpcipriv->btcoexist.b_fw_coexist_all_off = false;
+       } else {
+               h2c_parameter[2] = 0;
+               h2c_parameter[1] = 0;
+               h2c_parameter[0] = 0;
+       }
+       rtlpcipriv->btcoexist.b_balance_on = b_balance_on;
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n",
+               b_balance_on?"ON":"OFF", ms0, ms1,
+               h2c_parameter[0]<<16 | h2c_parameter[1]<<8 | h2c_parameter[2]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter);
+}
+
+
+void rtl8821ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+       if (type == BT_AGCTABLE_OFF) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BT]AGCTable Off!\n"));
+               rtl_write_dword(rtlpriv, 0xc78,0x641c0001);
+               rtl_write_dword(rtlpriv, 0xc78,0x631d0001);
+               rtl_write_dword(rtlpriv, 0xc78,0x621e0001);
+               rtl_write_dword(rtlpriv, 0xc78,0x611f0001);
+               rtl_write_dword(rtlpriv, 0xc78,0x60200001);
+
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_AGC_HP, 0xfffff, 0x32000);
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_AGC_HP, 0xfffff, 0x71000);
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_AGC_HP, 0xfffff, 0xb0000);
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_AGC_HP, 0xfffff, 0xfc000);
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_G1, 0xfffff, 0x30355);
+       } else if (type == BT_AGCTABLE_ON) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BT]AGCTable On!\n"));
+               rtl_write_dword(rtlpriv, 0xc78,0x4e1c0001);
+               rtl_write_dword(rtlpriv, 0xc78,0x4d1d0001);
+               rtl_write_dword(rtlpriv, 0xc78,0x4c1e0001);
+               rtl_write_dword(rtlpriv, 0xc78,0x4b1f0001);
+               rtl_write_dword(rtlpriv, 0xc78,0x4a200001);
+
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_AGC_HP, 0xfffff, 0xdc000);
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_AGC_HP, 0xfffff, 0x90000);
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_AGC_HP, 0xfffff, 0x51000);
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_AGC_HP, 0xfffff, 0x12000);
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A,
+                                       RF_RX_G1, 0xfffff, 0x00355);
+
+               rtlpcipriv->btcoexist.b_sw_coexist_all_off = false;
+       }
+}
+
+void rtl8821ae_dm_bt_bb_back_off_level(struct ieee80211_hw *hw, u8 type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+       if (type == BT_BB_BACKOFF_OFF) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BT]BBBackOffLevel Off!\n"));
+               rtl_write_dword(rtlpriv, 0xc04,0x3a05611);
+       } else if (type == BT_BB_BACKOFF_ON) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BT]BBBackOffLevel On!\n"));
+               rtl_write_dword(rtlpriv, 0xc04,0x3a07611);
+               rtlpcipriv->btcoexist.b_sw_coexist_all_off = false;
+       }
+}
+
+void rtl8821ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("rtl8821ae_dm_bt_fw_coex_all_off()\n"));
+
+       if(rtlpcipriv->btcoexist.b_fw_coexist_all_off)
+               return;
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("rtl8821ae_dm_bt_fw_coex_all_off(), real Do\n"));
+       rtl8821ae_dm_bt_fw_coex_all_off_8723a(hw);
+       rtlpcipriv->btcoexist.b_fw_coexist_all_off = true;
+}
+
+void rtl8821ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("rtl8821ae_dm_bt_sw_coex_all_off()\n"));
+
+       if(rtlpcipriv->btcoexist.b_sw_coexist_all_off)
+               return;
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("rtl8821ae_dm_bt_sw_coex_all_off(), real Do\n"));
+       rtl8821ae_dm_bt_sw_coex_all_off_8723a(hw);
+       rtlpcipriv->btcoexist.b_sw_coexist_all_off = true;
+}
+
+void rtl8821ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("rtl8821ae_dm_bt_hw_coex_all_off()\n"));
+
+       if(rtlpcipriv->btcoexist.b_hw_coexist_all_off)
+               return;
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("rtl8821ae_dm_bt_hw_coex_all_off(), real Do\n"));
+
+       rtl8821ae_dm_bt_hw_coex_all_off_8723a(hw);
+
+       rtlpcipriv->btcoexist.b_hw_coexist_all_off = true;
+}
+
+void rtl8821ae_btdm_coex_all_off(struct ieee80211_hw *hw)
+{
+       rtl8821ae_dm_bt_fw_coex_all_off(hw);
+       rtl8821ae_dm_bt_sw_coex_all_off(hw);
+       rtl8821ae_dm_bt_hw_coex_all_off(hw);
+}
+
+bool rtl8821ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+       if((rtlpcipriv->btcoexist.previous_state
+               == rtlpcipriv->btcoexist.current_state)
+               && (rtlpcipriv->btcoexist.previous_state_h
+               == rtlpcipriv->btcoexist.current_state_h))
+               return false;
+       else
+               return true;
+}
+
+bool rtl8821ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->link_info.b_tx_busy_traffic)
+               return true;
+       else
+               return false;
+}
+
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/hal_bt_coexist.h b/drivers/staging/rtl8821ae/rtl8821ae/hal_bt_coexist.h
new file mode 100644 (file)
index 0000000..799cc6f
--- /dev/null
@@ -0,0 +1,169 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_HAL_BT_COEXIST_H__
+#define __RTL8821AE_HAL_BT_COEXIST_H__
+
+#include "../wifi.h"
+
+/* The reg define is for 8723 */
+#define        REG_HIGH_PRIORITY_TXRX                  0x770
+#define        REG_LOW_PRIORITY_TXRX                   0x774
+
+#define BT_FW_COEX_THRESH_TOL                  6
+#define BT_FW_COEX_THRESH_20                   20
+#define BT_FW_COEX_THRESH_23                   23
+#define BT_FW_COEX_THRESH_25                   25
+#define BT_FW_COEX_THRESH_30                   30
+#define BT_FW_COEX_THRESH_35                   35
+#define BT_FW_COEX_THRESH_40                   40
+#define BT_FW_COEX_THRESH_45                   45
+#define BT_FW_COEX_THRESH_47                   47
+#define BT_FW_COEX_THRESH_50                   50
+#define BT_FW_COEX_THRESH_55                   55
+
+#define BT_COEX_STATE_BT30                             BIT(0)
+#define BT_COEX_STATE_WIFI_HT20                        BIT(1)
+#define BT_COEX_STATE_WIFI_HT40                        BIT(2)
+#define BT_COEX_STATE_WIFI_LEGACY              BIT(3)
+
+#define BT_COEX_STATE_WIFI_RSSI_LOW            BIT(4)
+#define BT_COEX_STATE_WIFI_RSSI_MEDIUM BIT(5)
+#define BT_COEX_STATE_WIFI_RSSI_HIGH   BIT(6)
+#define BT_COEX_STATE_DEC_BT_POWER             BIT(7)
+
+#define BT_COEX_STATE_WIFI_IDLE                        BIT(8)
+#define BT_COEX_STATE_WIFI_UPLINK              BIT(9)
+#define BT_COEX_STATE_WIFI_DOWNLINK            BIT(10)
+
+#define BT_COEX_STATE_BT_INQ_PAGE                      BIT(11)
+#define BT_COEX_STATE_BT_IDLE                  BIT(12)
+#define BT_COEX_STATE_BT_UPLINK                        BIT(13)
+#define BT_COEX_STATE_BT_DOWNLINK              BIT(14)
+
+#define BT_COEX_STATE_HOLD_FOR_BT_OPERATION    BIT(15)
+#define BT_COEX_STATE_BT_RSSI_LOW              BIT(19)
+
+#define BT_COEX_STATE_PROFILE_HID              BIT(20)
+#define BT_COEX_STATE_PROFILE_A2DP             BIT(21)
+#define BT_COEX_STATE_PROFILE_PAN              BIT(22)
+#define BT_COEX_STATE_PROFILE_SCO              BIT(23)
+
+#define BT_COEX_STATE_WIFI_RSSI_1_LOW          BIT(24)
+#define BT_COEX_STATE_WIFI_RSSI_1_MEDIUM       BIT(25)
+#define BT_COEX_STATE_WIFI_RSSI_1_HIGH         BIT(26)
+
+#define BT_COEX_STATE_BTINFO_COMMON                    BIT(30)
+#define BT_COEX_STATE_BTINFO_B_HID_SCOESCO     BIT(31)
+#define BT_COEX_STATE_BTINFO_B_FTP_A2DP                BIT(29)
+
+#define BT_COEX_STATE_BT_CNT_LEVEL_0           BIT(0)
+#define BT_COEX_STATE_BT_CNT_LEVEL_1           BIT(1)
+#define BT_COEX_STATE_BT_CNT_LEVEL_2           BIT(2)
+#define BT_COEX_STATE_BT_CNT_LEVEL_3           BIT(3)
+
+#define BT_RSSI_STATE_HIGH                     0
+#define BT_RSSI_STATE_MEDIUM           1
+#define BT_RSSI_STATE_LOW                      2
+#define BT_RSSI_STATE_STAY_HIGH                3
+#define BT_RSSI_STATE_STAY_MEDIUM      4
+#define BT_RSSI_STATE_STAY_LOW         5
+
+#define        BT_AGCTABLE_OFF                         0
+#define        BT_AGCTABLE_ON                          1
+#define        BT_BB_BACKOFF_OFF                       0
+#define        BT_BB_BACKOFF_ON                        1
+#define        BT_FW_NAV_OFF                           0
+#define        BT_FW_NAV_ON                            1
+
+#define        BT_COEX_MECH_NONE                       0
+#define        BT_COEX_MECH_SCO                        1
+#define        BT_COEX_MECH_HID                        2
+#define        BT_COEX_MECH_A2DP                       3
+#define        BT_COEX_MECH_PAN                        4
+#define        BT_COEX_MECH_HID_A2DP           5
+#define        BT_COEX_MECH_HID_PAN            6
+#define        BT_COEX_MECH_PAN_A2DP           7
+#define        BT_COEX_MECH_HID_SCO_ESCO       8
+#define        BT_COEX_MECH_FTP_A2DP           9
+#define        BT_COEX_MECH_COMMON                     10
+#define        BT_COEX_MECH_MAX                        11
+
+#define        BT_DBG_PROFILE_NONE                     0
+#define        BT_DBG_PROFILE_SCO                      1
+#define        BT_DBG_PROFILE_HID                      2
+#define        BT_DBG_PROFILE_A2DP                     3
+#define        BT_DBG_PROFILE_PAN                      4
+#define        BT_DBG_PROFILE_HID_A2DP         5
+#define        BT_DBG_PROFILE_HID_PAN          6
+#define        BT_DBG_PROFILE_PAN_A2DP         7
+#define        BT_DBG_PROFILE_MAX                      9
+
+#define        BTINFO_B_FTP                                    BIT(7)
+#define        BTINFO_B_A2DP                                   BIT(6)
+#define        BTINFO_B_HID                                    BIT(5)
+#define        BTINFO_B_SCO_BUSY                               BIT(4)
+#define        BTINFO_B_ACL_BUSY                               BIT(3)
+#define        BTINFO_B_INQ_PAGE                               BIT(2)
+#define        BTINFO_B_SCO_ESCO                               BIT(1)
+#define        BTINFO_B_CONNECTION                             BIT(0)
+
+
+void rtl8821ae_btdm_coex_all_off(struct ieee80211_hw *hw);
+void rtl8821ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw);
+
+void rtl8821ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw);
+void rtl8821ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw);
+long rtl8821ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw);
+void rtl8821ae_dm_bt_balance(struct ieee80211_hw *hw,
+                       bool b_balance_on, u8 ms0, u8 ms1);
+void rtl8821ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 tyep);
+void rtl8821ae_dm_bt_bb_back_off_level(struct ieee80211_hw *hw, u8 type);
+u8 rtl8821ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
+                                               u8      level_num, u8   rssi_thresh, u8 rssi_thresh1);
+u8 rtl8821ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
+                                       u8  level_num, u8   rssi_thresh, u8 rssi_thresh1);
+void _rtl8821ae_dm_bt_check_wifi_state(struct ieee80211_hw *hw);
+void rtl8821ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
+                       bool b_reject);
+
+#if 0
+VOID
+BTDM_PWDBMonitor(
+               PADAPTER        Adapter
+       );
+
+BOOLEAN
+BTDM_DIGByBTRSSI(
+                       PADAPTER        Adapter
+       );
+#endif
+bool rtl8821ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw);
+bool rtl8821ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw);
+#endif
+
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c b/drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c
new file mode 100644 (file)
index 0000000..79386ee
--- /dev/null
@@ -0,0 +1,2069 @@
+/******************************************************************************
+ *
+ * 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 "hal_btc.h"
+#include "../pci.h"
+#include "phy.h"
+#include "fw.h"
+#include "reg.h"
+#include "def.h"
+#include "../btcoexist/rtl_btc.h"
+
+static struct bt_coexist_8821ae hal_coex_8821ae;
+
+void rtl8821ae_dm_bt_turn_off_bt_coexist_before_enter_lps(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+    struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       if(!rtlpcipriv->btcoexist.bt_coexistence)
+               return;
+
+       if(ppsc->b_inactiveps) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,("[BT][DM], Before enter IPS, turn off all Coexist DM\n"));
+               rtlpcipriv->btcoexist.current_state = 0;
+               rtlpcipriv->btcoexist.previous_state = 0;
+               rtlpcipriv->btcoexist.current_state_h = 0;
+               rtlpcipriv->btcoexist.previous_state_h = 0;
+               rtl8821ae_btdm_coex_all_off(hw);
+       }
+}
+
+
+enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw)
+{
+    struct rtl_priv *rtlpriv = rtl_priv(hw);
+    struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+    enum rt_media_status    m_status = RT_MEDIA_DISCONNECT;
+
+    u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
+
+    if(bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
+            m_status = RT_MEDIA_CONNECT;
+    }
+
+    return m_status;
+}
+
+void rtl_8821ae_bt_wifi_media_status_notify(struct ieee80211_hw *hw, bool mstatus)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 h2c_parameter[3] ={0};
+       u8 chnl;
+
+       if(!rtlpcipriv->btcoexist.bt_coexistence)
+               return;
+
+       if(RT_MEDIA_CONNECT == mstatus)
+               h2c_parameter[0] = 0x1; // 0: disconnected, 1:connected
+       else
+               h2c_parameter[0] = 0x0;
+
+       if(mgnt_link_status_query(hw))  {
+               chnl = rtlphy->current_channel;
+               h2c_parameter[1] = chnl;
+       }
+
+       if(rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40){
+               h2c_parameter[2] = 0x30;
+       } else {
+               h2c_parameter[2] = 0x20;
+       }
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,("[BTCoex], FW write 0x19=0x%x\n",
+               h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x19, 3, h2c_parameter);
+
+}
+
+
+bool rtl8821ae_dm_bt_is_wifi_busy(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       if(rtlpriv->link_info.b_busytraffic ||
+               rtlpriv->link_info.b_rx_busy_traffic ||
+               rtlpriv->link_info.b_tx_busy_traffic)
+               return true;
+       else
+               return false;
+}
+void rtl8821ae_dm_bt_set_fw_3a(struct ieee80211_hw *hw,
+                                               u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       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;
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], FW write 0x3a(4bytes)=0x%x%8x\n",
+               h2c_parameter[0], h2c_parameter[1]<<24 | h2c_parameter[2]<<16 | h2c_parameter[3]<<8 | h2c_parameter[4]));
+       rtl8821ae_fill_h2c_cmd(hw, 0x3a, 5, h2c_parameter);
+}
+
+bool rtl8821ae_dm_bt_need_to_dec_bt_pwr(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Need to decrease bt power\n"));
+               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_DEC_BT_POWER;
+                       return true;
+       }
+
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_DEC_BT_POWER;
+       return false;
+}
+
+
+bool rtl8821ae_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+       if ((rtlpcipriv->btcoexist.previous_state
+               == rtlpcipriv->btcoexist.current_state)
+               &&(rtlpcipriv->btcoexist.previous_state_h
+               == rtlpcipriv->btcoexist.current_state_h)) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                               ("[DM][BT], Coexist state do not chang!!\n"));
+               return true;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                               ("[DM][BT], Coexist state changed!!\n"));
+               return false;
+       }
+}
+
+void rtl8821ae_dm_bt_set_coex_table(struct ieee80211_hw *hw,
+                                               u32 val_0x6c0, u32 val_0x6c8, u32 val_0x6cc)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("set coex table, set 0x6c0=0x%x\n", val_0x6c0));
+       rtl_write_dword(rtlpriv, 0x6c0, val_0x6c0);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("set coex table, set 0x6c8=0x%x\n", val_0x6c8));
+       rtl_write_dword(rtlpriv, 0x6c8, val_0x6c8);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("set coex table, set 0x6cc=0x%x\n", val_0x6cc));
+       rtl_write_byte(rtlpriv, 0x6cc, val_0x6cc);
+}
+
+void rtl8821ae_dm_bt_set_hw_pta_mode(struct ieee80211_hw *hw, bool b_mode)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (BT_PTA_MODE_ON == b_mode) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("PTA mode on, "));
+               /*  Enable GPIO 0/1/2/3/8 pins for bt */
+               rtl_write_byte(rtlpriv, 0x40, 0x20);
+               rtlpcipriv->btcoexist.b_hw_coexist_all_off = false;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("PTA mode off\n"));
+               rtl_write_byte(rtlpriv, 0x40, 0x0);
+       }
+}
+
+void rtl8821ae_dm_bt_set_sw_rf_rx_lpf_corner(struct ieee80211_hw *hw, u8 type)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (BT_RF_RX_LPF_CORNER_SHRINK == type) {
+               /* Shrink RF Rx LPF corner, 0x1e[7:4]=1111 ==> [11:4] by Jenyu */
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Shrink RF Rx LPF corner!!\n"));
+               /* PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)PathA, 0x1e, 0xf0, 0xf); */
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff, 0xf0ff7);
+               rtlpcipriv->btcoexist.b_sw_coexist_all_off = false;
+       } else if(BT_RF_RX_LPF_CORNER_RESUME == type) {
+               /*Resume RF Rx LPF corner*/
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Resume RF Rx LPF corner!!\n"));
+               /* PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)PathA, 0x1e, 0xf0,
+                * pHalData->btcoexist.BtRfRegOrigin1E); */
+               rtl8821ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff,
+                       rtlpcipriv->btcoexist.bt_rfreg_origin_1e);
+       }
+}
+
+void rtl8821ae_dm_bt_set_sw_penalty_tx_rate_adaptive(struct ieee80211_hw *hw,
+                                                                                                                                       u8 ra_type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       u8 tmp_u1;
+
+       tmp_u1 = rtl_read_byte(rtlpriv, 0x4fd);
+       tmp_u1 |= BIT(0);
+       if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == ra_type) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Tx rate adaptive, set low penalty!!\n"));
+               tmp_u1 &= ~BIT(2);
+               rtlpcipriv->btcoexist.b_sw_coexist_all_off = false;
+       } else if(BT_TX_RATE_ADAPTIVE_NORMAL == ra_type) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Tx rate adaptive, set normal!!\n"));
+               tmp_u1 |= BIT(2);
+       }
+
+       rtl_write_byte(rtlpriv, 0x4fd, tmp_u1);
+}
+
+void rtl8821ae_dm_bt_btdm_structure_reload(struct ieee80211_hw *hw,
+                                                                                                       struct btdm_8821ae      *p_btdm)
+{
+       p_btdm->b_all_off = false;
+       p_btdm->b_agc_table_en = false;
+       p_btdm->b_adc_back_off_on = false;
+       p_btdm->b2_ant_hid_en = false;
+       p_btdm->b_low_penalty_rate_adaptive = false;
+       p_btdm->b_rf_rx_lpf_shrink = false;
+       p_btdm->b_reject_aggre_pkt= false;
+
+       p_btdm->b_tdma_on = false;
+       p_btdm->tdma_ant = TDMA_2ANT;
+       p_btdm->tdma_nav = TDMA_NAV_OFF;
+       p_btdm->tdma_dac_swing = TDMA_DAC_SWING_OFF;
+       p_btdm->fw_dac_swing_lvl = 0x20;
+
+       p_btdm->b_tra_tdma_on = false;
+       p_btdm->tra_tdma_ant = TDMA_2ANT;
+       p_btdm->tra_tdma_nav = TDMA_NAV_OFF;
+       p_btdm->b_ignore_wlan_act = false;
+
+       p_btdm->b_ps_tdma_on = false;
+       p_btdm->ps_tdma_byte[0] = 0x0;
+       p_btdm->ps_tdma_byte[1] = 0x0;
+       p_btdm->ps_tdma_byte[2] = 0x0;
+       p_btdm->ps_tdma_byte[3] = 0x8;
+       p_btdm->ps_tdma_byte[4] = 0x0;
+
+       p_btdm->b_pta_on = true;
+       p_btdm->val_0x6c0 = 0x5a5aaaaa;
+       p_btdm->val_0x6c8 = 0xcc;
+       p_btdm->val_0x6cc = 0x3;
+
+       p_btdm->b_sw_dac_swing_on = false;
+       p_btdm->sw_dac_swing_lvl = 0xc0;
+       p_btdm->wlan_act_hi = 0x20;
+       p_btdm->wlan_act_lo = 0x10;
+       p_btdm->bt_retry_index = 2;
+
+       p_btdm->b_dec_bt_pwr = false;
+}
+
+void rtl8821ae_dm_bt_btdm_structure_reload_all_off(struct ieee80211_hw *hw,
+                                                                                                       struct btdm_8821ae      *p_btdm)
+{
+       rtl8821ae_dm_bt_btdm_structure_reload(hw, p_btdm);
+       p_btdm->b_all_off = true;
+       p_btdm->b_pta_on = false;
+       p_btdm->wlan_act_hi = 0x10;
+}
+
+bool rtl8821ae_dm_bt_is_2_ant_common_action(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct btdm_8821ae btdm8821ae;
+       bool b_common = false;
+
+       rtl8821ae_dm_bt_btdm_structure_reload(hw, &btdm8821ae);
+
+       if(!rtl8821ae_dm_bt_is_wifi_busy(hw)
+               && !rtlpcipriv->btcoexist.b_bt_busy) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("Wifi idle + Bt idle, bt coex mechanism always off!!\n"));
+               rtl8821ae_dm_bt_btdm_structure_reload_all_off(hw, &btdm8821ae);
+               b_common = true;
+       } else if (rtl8821ae_dm_bt_is_wifi_busy(hw)
+               && !rtlpcipriv->btcoexist.b_bt_busy) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("Wifi non-idle + Bt disabled/idle!!\n"));
+               btdm8821ae.b_low_penalty_rate_adaptive = true;
+               btdm8821ae.b_rf_rx_lpf_shrink = false;
+               btdm8821ae.b_reject_aggre_pkt = false;
+
+               /* sw mechanism */
+               btdm8821ae.b_agc_table_en = false;
+               btdm8821ae.b_adc_back_off_on = false;
+               btdm8821ae.b_sw_dac_swing_on = false;
+
+               btdm8821ae.b_pta_on = true;
+               btdm8821ae.val_0x6c0 = 0x5a5aaaaa;
+               btdm8821ae.val_0x6c8 = 0xcccc;
+               btdm8821ae.val_0x6cc = 0x3;
+
+               btdm8821ae.b_tdma_on = false;
+               btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_OFF;
+               btdm8821ae.b2_ant_hid_en = false;
+
+               b_common = true;
+       }else if (rtlpcipriv->btcoexist.b_bt_busy) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("Bt non-idle!\n"));
+               if(mgnt_link_status_query(hw) == RT_MEDIA_CONNECT){
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi connection exist\n"))
+                       b_common = false;
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                               ("No Wifi connection!\n"));
+                       btdm8821ae.b_rf_rx_lpf_shrink = true;
+                       btdm8821ae.b_low_penalty_rate_adaptive = false;
+                       btdm8821ae.b_reject_aggre_pkt = false;
+
+                       /* sw mechanism */
+                       btdm8821ae.b_agc_table_en = false;
+                       btdm8821ae.b_adc_back_off_on = false;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+
+                       btdm8821ae.b_pta_on = true;
+                       btdm8821ae.val_0x6c0 = 0x55555555;
+                       btdm8821ae.val_0x6c8 = 0x0000ffff;
+                       btdm8821ae.val_0x6cc = 0x3;
+
+                       btdm8821ae.b_tdma_on = false;
+                       btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_OFF;
+                       btdm8821ae.b2_ant_hid_en = false;
+
+                       b_common = true;
+               }
+       }
+
+       if (rtl8821ae_dm_bt_need_to_dec_bt_pwr(hw)) {
+               btdm8821ae.b_dec_bt_pwr = true;
+       }
+
+       if(b_common)
+                rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_BTINFO_COMMON;
+
+       if (b_common && rtl8821ae_dm_bt_is_coexist_state_changed(hw))
+               rtl8821ae_dm_bt_set_bt_dm(hw, &btdm8821ae);
+
+       return b_common;
+}
+
+void rtl8821ae_dm_bt_set_sw_full_time_dac_swing(
+               struct ieee80211_hw * hw, bool b_sw_dac_swing_on, u32 sw_dac_swing_lvl)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (b_sw_dac_swing_on) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl));
+               rtl8821ae_phy_set_bb_reg(hw, 0x880, 0xff000000, sw_dac_swing_lvl);
+               rtlpcipriv->btcoexist.b_sw_coexist_all_off = false;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], SwDacSwing Off!\n"));
+               rtl8821ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0);
+       }
+}
+
+void rtl8821ae_dm_bt_set_fw_dec_bt_pwr(
+               struct ieee80211_hw *hw, bool b_dec_bt_pwr)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 h2c_parameter[1] ={0};
+
+       h2c_parameter[0] = 0;
+
+       if (b_dec_bt_pwr) {
+               h2c_parameter[0] |= BIT(1);
+               rtlpcipriv->btcoexist.b_fw_coexist_all_off = false;
+       }
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], decrease Bt Power : %s, write 0x21=0x%x\n",
+               (b_dec_bt_pwr? "Yes!!":"No!!"), h2c_parameter[0]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x21, 1, h2c_parameter);
+}
+
+
+void rtl8821ae_dm_bt_set_fw_2_ant_hid(struct ieee80211_hw *hw,
+                                                                       bool b_enable, bool b_dac_swing_on)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 h2c_parameter[1] ={0};
+
+       if (b_enable) {
+               h2c_parameter[0] |= BIT(0);
+               rtlpcipriv->btcoexist.b_fw_coexist_all_off = false;
+       }
+       if (b_dac_swing_on) {
+               h2c_parameter[0] |= BIT(1); /* Dac Swing default enable */
+       }
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], turn 2-Ant+HID mode %s, DACSwing:%s, write 0x15=0x%x\n",
+               (b_enable ? "ON!!":"OFF!!"), (b_dac_swing_on ? "ON":"OFF"),
+               h2c_parameter[0]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x15, 1, h2c_parameter);
+}
+
+void rtl8821ae_dm_bt_set_fw_tdma_ctrl(struct ieee80211_hw *hw,
+                               bool b_enable, u8 ant_num, u8 nav_en, u8 dac_swing_en)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       u8 h2c_parameter[1] ={0};
+       u8 h2c_parameter1[1] = {0};
+
+       h2c_parameter[0] = 0;
+       h2c_parameter1[0] = 0;
+
+       if(b_enable) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], set BT PTA update manager to trigger update!!\n"));
+               h2c_parameter1[0] |= BIT(0);
+
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], turn TDMA mode ON!!\n"));
+               h2c_parameter[0] |= BIT(0);             /* function enable */
+               if (TDMA_1ANT == ant_num) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], TDMA_1ANT\n"));
+                       h2c_parameter[0] |= BIT(1);
+               } else if(TDMA_2ANT == ant_num) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], TDMA_2ANT\n"));
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], Unknown Ant\n"));
+               }
+
+               if (TDMA_NAV_OFF == nav_en) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], TDMA_NAV_OFF\n"));
+               } else if (TDMA_NAV_ON == nav_en) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], TDMA_NAV_ON\n"));
+                       h2c_parameter[0] |= BIT(2);
+               }
+
+               if (TDMA_DAC_SWING_OFF == dac_swing_en) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                               ("[BTCoex], TDMA_DAC_SWING_OFF\n"));
+               } else if(TDMA_DAC_SWING_ON == dac_swing_en) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                               ("[BTCoex], TDMA_DAC_SWING_ON\n"));
+                       h2c_parameter[0] |= BIT(4);
+               }
+               rtlpcipriv->btcoexist.b_fw_coexist_all_off = false;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], set BT PTA update manager to no update!!\n"));
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], turn TDMA mode OFF!!\n"));
+       }
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], FW2AntTDMA, write 0x26=0x%x\n", h2c_parameter1[0]));
+       rtl8821ae_fill_h2c_cmd(hw, 0x26, 1, h2c_parameter1);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], FW2AntTDMA, write 0x14=0x%x\n", h2c_parameter[0]));
+       rtl8821ae_fill_h2c_cmd(hw, 0x14, 1, h2c_parameter);
+
+       if (!b_enable) {
+               /* delay_ms(2);
+                * PlatformEFIOWrite1Byte(Adapter, 0x778, 0x1); */
+       }
+}
+
+
+void rtl8821ae_dm_bt_set_fw_ignore_wlan_act( struct ieee80211_hw *hw, bool b_enable)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       u8 h2c_parameter[1] ={0};
+
+       if (b_enable) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], BT Ignore Wlan_Act !!\n"));
+               h2c_parameter[0] |= BIT(0);             // function enable
+               rtlpcipriv->btcoexist.b_fw_coexist_all_off = false;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], BT don't ignore Wlan_Act !!\n"));
+       }
+
+    RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25=0x%x\n",
+               h2c_parameter[0]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x25, 1, h2c_parameter);
+}
+
+
+void rtl8821ae_dm_bt_set_fw_tra_tdma_ctrl(struct ieee80211_hw *hw,
+               bool b_enable, u8 ant_num, u8 nav_en
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       //struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       u8 h2c_parameter[2] ={0};
+
+
+       if (b_enable) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], turn TTDMA mode ON!!\n"));
+               h2c_parameter[0] |= BIT(0);             // function enable
+               if (TDMA_1ANT == ant_num) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], TTDMA_1ANT\n"));
+                       h2c_parameter[0] |= BIT(1);
+               } else if (TDMA_2ANT == ant_num) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], TTDMA_2ANT\n"));
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], Unknown Ant\n"));
+               }
+
+               if (TDMA_NAV_OFF == nav_en) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], TTDMA_NAV_OFF\n"));
+               } else if (TDMA_NAV_ON == nav_en) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], TTDMA_NAV_ON\n"));
+                       h2c_parameter[1] |= BIT(0);
+               }
+
+               rtlpcipriv->btcoexist.b_fw_coexist_all_off = false;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], turn TTDMA mode OFF!!\n"));
+       }
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], FW Traditional TDMA, write 0x33=0x%x\n",
+               h2c_parameter[0] << 8| h2c_parameter[1]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x33, 2, h2c_parameter);
+}
+
+
+void rtl8821ae_dm_bt_set_fw_dac_swing_level(struct ieee80211_hw *hw,
+                                                                                                       u8 dac_swing_lvl)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 h2c_parameter[1] ={0};
+       h2c_parameter[0] = dac_swing_lvl;
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], Set Dac Swing Level=0x%x\n", dac_swing_lvl));
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], write 0x29=0x%x\n", h2c_parameter[0]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x29, 1, h2c_parameter);
+}
+
+void rtl8821ae_dm_bt_set_fw_bt_hid_info(struct ieee80211_hw *hw, bool b_enable)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 h2c_parameter[1] ={0};
+       h2c_parameter[0] = 0;
+
+       if(b_enable){
+               h2c_parameter[0] |= BIT(0);
+               rtlpcipriv->btcoexist.b_fw_coexist_all_off = false;
+       }
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], Set BT HID information=0x%x\n", b_enable));
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], write 0x24=0x%x\n", h2c_parameter[0]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x24, 1, h2c_parameter);
+}
+
+void rtl8821ae_dm_bt_set_fw_bt_retry_index(struct ieee80211_hw *hw,
+                                                                                                       u8 retry_index)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 h2c_parameter[1] ={0};
+       h2c_parameter[0] = retry_index;
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], Set BT Retry Index=%d\n", retry_index));
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], write 0x23=0x%x\n", h2c_parameter[0]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x23, 1, h2c_parameter);
+}
+
+void rtl8821ae_dm_bt_set_fw_wlan_act(struct ieee80211_hw *hw,
+                                                                                       u8 wlan_act_hi, u8 wlan_act_lo)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 h2c_parameter_hi[1] ={0};
+       u8 h2c_parameter_lo[1] ={0};
+       h2c_parameter_hi[0] = wlan_act_hi;
+       h2c_parameter_lo[0] = wlan_act_lo;
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], Set WLAN_ACT Hi:Lo=0x%x/0x%x\n", wlan_act_hi, wlan_act_lo));
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], write 0x22=0x%x\n", h2c_parameter_hi[0]));
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("[BTCoex], write 0x11=0x%x\n", h2c_parameter_lo[0]));
+
+       /* WLAN_ACT = High duration, unit:ms */
+       rtl8821ae_fill_h2c_cmd(hw, 0x22, 1, h2c_parameter_hi);
+       /*  WLAN_ACT = Low duration, unit:3*625us */
+       rtl8821ae_fill_h2c_cmd(hw, 0x11, 1, h2c_parameter_lo);
+}
+
+void rtl8821ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, struct btdm_8821ae *p_btdm)
+{
+       struct rtl_pci_priv     *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct btdm_8821ae *p_btdm_8821ae = &hal_coex_8821ae.btdm;
+       u8 i;
+
+       bool b_fw_current_inpsmode = false;
+    bool b_fw_ps_awake = true;
+
+    rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+                                             (u8 *) (&b_fw_current_inpsmode));
+    rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
+                                             (u8 *) (&b_fw_ps_awake));
+
+       // check new setting is different with the old one,
+       // if all the same, don't do the setting again.
+       if (memcmp(p_btdm_8821ae, p_btdm, sizeof(struct btdm_8821ae)) == 0) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], the same coexist setting, return!!\n"));
+               return;
+       } else {        //save the new coexist setting
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], UPDATE TO NEW COEX SETTING!!\n"));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new bAllOff=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_all_off, p_btdm->b_all_off));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new b_agc_table_en=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_agc_table_en, p_btdm->b_agc_table_en));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new b_adc_back_off_on=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_adc_back_off_on, p_btdm->b_adc_back_off_on));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new b2_ant_hid_en=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b2_ant_hid_en, p_btdm->b2_ant_hid_en));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new bLowPenaltyRateAdaptive=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_low_penalty_rate_adaptive,
+                       p_btdm->b_low_penalty_rate_adaptive));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new bRfRxLpfShrink=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_rf_rx_lpf_shrink, p_btdm->b_rf_rx_lpf_shrink));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new bRejectAggrePkt=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_reject_aggre_pkt, p_btdm->b_reject_aggre_pkt));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new b_tdma_on=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_tdma_on, p_btdm->b_tdma_on));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new tdmaAnt=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->tdma_ant, p_btdm->tdma_ant));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new tdmaNav=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->tdma_nav, p_btdm->tdma_nav));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new tdma_dac_swing=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->tdma_dac_swing, p_btdm->tdma_dac_swing));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new fw_dac_swing_lvl=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->fw_dac_swing_lvl, p_btdm->fw_dac_swing_lvl));
+
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new bTraTdmaOn=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_tra_tdma_on, p_btdm->b_tra_tdma_on));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new traTdmaAnt=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->tra_tdma_ant, p_btdm->tra_tdma_ant));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new traTdmaNav=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->tra_tdma_nav, p_btdm->tra_tdma_nav));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new bPsTdmaOn=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_ps_tdma_on, p_btdm->b_ps_tdma_on));
+               for(i=0; i<5; i++)
+               {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                               ("[BTCoex], original/new psTdmaByte[i]=0x%x/ 0x%x \n",
+                               p_btdm_8821ae->ps_tdma_byte[i], p_btdm->ps_tdma_byte[i]));
+               }
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new bIgnoreWlanAct=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_ignore_wlan_act, p_btdm->b_ignore_wlan_act));
+
+
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new bPtaOn=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_pta_on, p_btdm->b_pta_on));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new val_0x6c0=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->val_0x6c0, p_btdm->val_0x6c0));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new val_0x6c8=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->val_0x6c8, p_btdm->val_0x6c8));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new val_0x6cc=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->val_0x6cc, p_btdm->val_0x6cc));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new b_sw_dac_swing_on=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->b_sw_dac_swing_on, p_btdm->b_sw_dac_swing_on));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new sw_dac_swing_lvl=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->sw_dac_swing_lvl, p_btdm->sw_dac_swing_lvl));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new wlanActHi=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->wlan_act_hi, p_btdm->wlan_act_hi));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new wlanActLo=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->wlan_act_lo, p_btdm->wlan_act_lo));
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], original/new btRetryIndex=0x%x/ 0x%x \n",
+                       p_btdm_8821ae->bt_retry_index, p_btdm->bt_retry_index));
+
+               memcpy(p_btdm_8821ae, p_btdm, sizeof(struct btdm_8821ae));
+       }
+       /*
+        * Here we only consider when Bt Operation
+        * inquiry/paging/pairing is ON
+        * we only need to turn off TDMA */
+
+       if (rtlpcipriv->btcoexist.b_hold_for_bt_operation) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], set to ignore wlanAct for BT OP!!\n"));
+               rtl8821ae_dm_bt_set_fw_ignore_wlan_act(hw, true);
+               return;
+       }
+
+       if (p_btdm->b_all_off) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("[BTCoex], disable all coexist mechanism !!\n"));
+               rtl8821ae_btdm_coex_all_off(hw);
+               return;
+       }
+
+       rtl8821ae_dm_bt_reject_ap_aggregated_packet(hw, p_btdm->b_reject_aggre_pkt);
+
+       if(p_btdm->b_low_penalty_rate_adaptive)
+               rtl8821ae_dm_bt_set_sw_penalty_tx_rate_adaptive(hw,
+                       BT_TX_RATE_ADAPTIVE_LOW_PENALTY);
+       else
+               rtl8821ae_dm_bt_set_sw_penalty_tx_rate_adaptive(hw,
+                       BT_TX_RATE_ADAPTIVE_NORMAL);
+
+       if(p_btdm->b_rf_rx_lpf_shrink)
+               rtl8821ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_SHRINK);
+       else
+               rtl8821ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME);
+
+       if(p_btdm->b_agc_table_en)
+               rtl8821ae_dm_bt_agc_table(hw, BT_AGCTABLE_ON);
+       else
+               rtl8821ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF);
+
+       if(p_btdm->b_adc_back_off_on)
+               rtl8821ae_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_ON);
+       else
+               rtl8821ae_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_OFF);
+
+       rtl8821ae_dm_bt_set_fw_bt_retry_index(hw, p_btdm->bt_retry_index);
+
+       rtl8821ae_dm_bt_set_fw_dac_swing_level(hw, p_btdm->fw_dac_swing_lvl);
+       rtl8821ae_dm_bt_set_fw_wlan_act(hw, p_btdm->wlan_act_hi, p_btdm->wlan_act_lo);
+
+       rtl8821ae_dm_bt_set_coex_table(hw, p_btdm->val_0x6c0,
+               p_btdm->val_0x6c8, p_btdm->val_0x6cc);
+       rtl8821ae_dm_bt_set_hw_pta_mode(hw, p_btdm->b_pta_on);
+
+       /*
+        * Note: There is a constraint between TDMA and 2AntHID
+        * Only one of 2AntHid and tdma can be turn on
+        * We should turn off those mechanisms should be turned off first
+        * and then turn on those mechanisms should be turned on.
+       */
+#if 1
+       if(p_btdm->b2_ant_hid_en) {
+               // turn off tdma
+               rtl8821ae_dm_bt_set_fw_tra_tdma_ctrl(hw, p_btdm->b_tra_tdma_on,
+                                                       p_btdm->tra_tdma_ant, p_btdm->tra_tdma_nav);
+               rtl8821ae_dm_bt_set_fw_tdma_ctrl(hw, false, p_btdm->tdma_ant,
+                                                       p_btdm->tdma_nav, p_btdm->tdma_dac_swing);
+
+               // turn off Pstdma
+               rtl8821ae_dm_bt_set_fw_ignore_wlan_act(hw, p_btdm->b_ignore_wlan_act);
+               rtl8821ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);         // Antenna control by PTA, 0x870 = 0x300.
+
+               // turn on 2AntHid
+               rtl8821ae_dm_bt_set_fw_bt_hid_info(hw, true);
+               rtl8821ae_dm_bt_set_fw_2_ant_hid(hw, true, true);
+       } else if(p_btdm->b_tdma_on) {
+               // turn off 2AntHid
+               rtl8821ae_dm_bt_set_fw_bt_hid_info(hw, false);
+               rtl8821ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
+
+               // turn off pstdma
+               rtl8821ae_dm_bt_set_fw_ignore_wlan_act(hw, p_btdm->b_ignore_wlan_act);
+               rtl8821ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);         // Antenna control by PTA, 0x870 = 0x300.
+
+               // turn on tdma
+               rtl8821ae_dm_bt_set_fw_tra_tdma_ctrl(hw, p_btdm->b_tra_tdma_on, p_btdm->tra_tdma_ant, p_btdm->tra_tdma_nav);
+               rtl8821ae_dm_bt_set_fw_tdma_ctrl(hw, true, p_btdm->tdma_ant, p_btdm->tdma_nav, p_btdm->tdma_dac_swing);
+       } else if(p_btdm->b_ps_tdma_on) {
+               // turn off 2AntHid
+               rtl8821ae_dm_bt_set_fw_bt_hid_info(hw, false);
+               rtl8821ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
+
+               // turn off tdma
+               rtl8821ae_dm_bt_set_fw_tra_tdma_ctrl(hw, p_btdm->b_tra_tdma_on, p_btdm->tra_tdma_ant, p_btdm->tra_tdma_nav);
+               rtl8821ae_dm_bt_set_fw_tdma_ctrl(hw, false, p_btdm->tdma_ant, p_btdm->tdma_nav, p_btdm->tdma_dac_swing);
+
+               // turn on pstdma
+               rtl8821ae_dm_bt_set_fw_ignore_wlan_act(hw, p_btdm->b_ignore_wlan_act);
+               rtl8821ae_dm_bt_set_fw_3a(hw,
+                       p_btdm->ps_tdma_byte[0],
+                       p_btdm->ps_tdma_byte[1],
+                       p_btdm->ps_tdma_byte[2],
+                       p_btdm->ps_tdma_byte[3],
+                       p_btdm->ps_tdma_byte[4]);
+       } else {
+               // turn off 2AntHid
+               rtl8821ae_dm_bt_set_fw_bt_hid_info(hw, false);
+               rtl8821ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
+
+               // turn off tdma
+               rtl8821ae_dm_bt_set_fw_tra_tdma_ctrl(hw, p_btdm->b_tra_tdma_on, p_btdm->tra_tdma_ant, p_btdm->tra_tdma_nav);
+               rtl8821ae_dm_bt_set_fw_tdma_ctrl(hw, false, p_btdm->tdma_ant, p_btdm->tdma_nav, p_btdm->tdma_dac_swing);
+
+               // turn off pstdma
+               rtl8821ae_dm_bt_set_fw_ignore_wlan_act(hw, p_btdm->b_ignore_wlan_act);
+               rtl8821ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);         // Antenna control by PTA, 0x870 = 0x300.
+       }
+#else
+       if (p_btdm->b_tdma_on) {
+               if(p_btdm->b_ps_tdma_on) {
+               } else {
+                       rtl8821ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
+               }
+               /* Turn off 2AntHID first then turn tdma ON */
+               rtl8821ae_dm_bt_set_fw_bt_hid_info(hw, false);
+               rtl8821ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
+               rtl8821ae_dm_bt_set_fw_tra_tdma_ctrl(hw, p_btdm->b_tra_tdma_on, p_btdm->tra_tdma_ant, p_btdm->tra_tdma_nav);
+               rtl8821ae_dm_bt_set_fw_tdma_ctrl(hw, true,
+                       p_btdm->tdma_ant, p_btdm->tdma_nav, p_btdm->tdma_dac_swing);
+       } else {
+               /* Turn off tdma first then turn 2AntHID ON if need */
+               rtl8821ae_dm_bt_set_fw_tra_tdma_ctrl(hw, p_btdm->b_tra_tdma_on, p_btdm->tra_tdma_ant, p_btdm->tra_tdma_nav);
+               rtl8821ae_dm_bt_set_fw_tdma_ctrl(hw, false, p_btdm->tdma_ant,
+                       p_btdm->tdma_nav, p_btdm->tdma_dac_swing);
+               if (p_btdm->b2_ant_hid_en) {
+                       rtl8821ae_dm_bt_set_fw_bt_hid_info(hw, true);
+                       rtl8821ae_dm_bt_set_fw_2_ant_hid(hw, true, true);
+               } else {
+                       rtl8821ae_dm_bt_set_fw_bt_hid_info(hw, false);
+                       rtl8821ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
+               }
+               if(p_btdm->b_ps_tdma_on) {
+                       rtl8821ae_dm_bt_set_fw_3a(hw, p_btdm->ps_tdma_byte[0], p_btdm->ps_tdma_byte[1],
+                               p_btdm->ps_tdma_byte[2], p_btdm->ps_tdma_byte[3], p_btdm->ps_tdma_byte[4]);
+               } else {
+                       rtl8821ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
+               }
+       }
+#endif
+
+       /*
+        * Note:
+        * We should add delay for making sure sw DacSwing can be set sucessfully.
+        * because of that rtl8821ae_dm_bt_set_fw_2_ant_hid() and rtl8821ae_dm_bt_set_fw_tdma_ctrl()
+        * will overwrite the reg 0x880.
+       */
+       mdelay(30);
+       rtl8821ae_dm_bt_set_sw_full_time_dac_swing(hw,
+               p_btdm->b_sw_dac_swing_on, p_btdm->sw_dac_swing_lvl);
+       rtl8821ae_dm_bt_set_fw_dec_bt_pwr(hw, p_btdm->b_dec_bt_pwr);
+}
+
+void rtl8821ae_dm_bt_bt_state_update_2_ant_hid(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], HID busy!!\n"));
+       rtlpcipriv->btcoexist.b_bt_busy = true;
+       rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_BT_IDLE;
+}
+
+void rtl8821ae_dm_bt_bt_state_update_2_ant_pan(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       bool b_idle = false;
+
+       if (hal_coex_8821ae.low_priority_tx >=
+               hal_coex_8821ae.low_priority_rx) {
+               if((hal_coex_8821ae.low_priority_tx/
+                       hal_coex_8821ae.low_priority_rx) > 10) {
+                       b_idle = true;
+               }
+       } else {
+               if((hal_coex_8821ae.low_priority_rx/
+                       hal_coex_8821ae.low_priority_tx) > 10) {
+                       b_idle = true;
+               }
+       }
+
+       if(!b_idle) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], PAN busy!!\n"));
+               rtlpcipriv->btcoexist.b_bt_busy = true;
+               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_BT_IDLE;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], PAN idle!!\n"));
+       }
+}
+
+void rtl8821ae_dm_bt_2_ant_sco_action(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct btdm_8821ae btdm8821ae;
+       u8 bt_rssi_state;
+
+       rtl8821ae_dm_bt_btdm_structure_reload(hw, &btdm8821ae);
+       btdm8821ae.b_rf_rx_lpf_shrink = true;
+       btdm8821ae.b_low_penalty_rate_adaptive = true;
+       btdm8821ae.b_reject_aggre_pkt = false;
+
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("HT40\n"));
+               /*  coex table */
+               btdm8821ae.val_0x6c0 = 0x5a5aaaaa;
+               btdm8821ae.val_0x6c8 = 0xcc;
+               btdm8821ae.val_0x6cc = 0x3;
+               /* sw mechanism */
+               btdm8821ae.b_agc_table_en = false;
+               btdm8821ae.b_adc_back_off_on = true;
+               btdm8821ae.b_sw_dac_swing_on = false;
+               /* fw mechanism */
+               btdm8821ae.b_tdma_on = false;
+               btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_OFF;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("HT20 or Legacy\n"));
+               bt_rssi_state
+                       = rtl8821ae_dm_bt_check_coex_rssi_state(hw, 2, BT_FW_COEX_THRESH_47, 0);
+
+               /* coex table */
+               btdm8821ae.val_0x6c0 = 0x5a5aaaaa;
+               btdm8821ae.val_0x6c8 = 0xcc;
+               btdm8821ae.val_0x6cc = 0x3;
+               /* sw mechanism */
+               if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
+                       (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH) ) {
+                       btdm8821ae.b_agc_table_en = true;
+                       btdm8821ae.b_adc_back_off_on = true;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+               } else {
+                       btdm8821ae.b_agc_table_en = false;
+                       btdm8821ae.b_adc_back_off_on = false;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+               }
+               /* fw mechanism */
+               btdm8821ae.b_tdma_on = false;
+               btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_OFF;
+       }
+
+       if (rtl8821ae_dm_bt_need_to_dec_bt_pwr(hw)) {
+               btdm8821ae.b_dec_bt_pwr = true;
+       }
+
+       if(rtl8821ae_dm_bt_is_coexist_state_changed(hw))
+               rtl8821ae_dm_bt_set_bt_dm(hw, &btdm8821ae);
+}
+
+void rtl8821ae_dm_bt_2_ant_hid_action(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct btdm_8821ae btdm8821ae;
+       u8 bt_rssi_state;
+
+       rtl8821ae_dm_bt_btdm_structure_reload(hw, &btdm8821ae);
+
+       btdm8821ae.b_rf_rx_lpf_shrink = true;
+       btdm8821ae.b_low_penalty_rate_adaptive = true;
+       btdm8821ae.b_reject_aggre_pkt = false;
+
+       // coex table
+       btdm8821ae.val_0x6c0 = 0x55555555;
+       btdm8821ae.val_0x6c8 = 0xffff;
+       btdm8821ae.val_0x6cc = 0x3;
+       btdm8821ae.b_ignore_wlan_act = true;
+
+       if(rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("HT40\n"));
+               // sw mechanism
+               btdm8821ae.b_agc_table_en = false;
+               btdm8821ae.b_adc_back_off_on = false;
+               btdm8821ae.b_sw_dac_swing_on = false;
+
+               // fw mechanism
+               btdm8821ae.b_ps_tdma_on = true;
+               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+               btdm8821ae.ps_tdma_byte[1] = 0xf;
+               btdm8821ae.ps_tdma_byte[2] = 0xf;
+               btdm8821ae.ps_tdma_byte[3] = 0x0;
+               btdm8821ae.ps_tdma_byte[4] = 0x80;
+
+               btdm8821ae.b_tra_tdma_on = false;
+               btdm8821ae.b_tdma_on = false;
+               btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_OFF;
+               btdm8821ae.b2_ant_hid_en = false;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("HT20 or Legacy\n"));
+               bt_rssi_state =
+                       rtl8821ae_dm_bt_check_coex_rssi_state(hw, 2, 47, 0);
+
+               if( (bt_rssi_state == BT_RSSI_STATE_HIGH) ||
+                       (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH) ) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi high \n"));
+                       // sw mechanism
+                       btdm8821ae.b_agc_table_en = false;
+                       btdm8821ae.b_adc_back_off_on = false;
+                       btdm8821ae.b_sw_dac_swing_on = true;
+                       btdm8821ae.sw_dac_swing_lvl = 0x20;
+
+                       // fw mechanism
+                       btdm8821ae.b_ps_tdma_on = false;
+                       btdm8821ae.b_tdma_on = false;
+                       btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_OFF;
+                       btdm8821ae.b2_ant_hid_en = false;
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi low \n"));
+                       // sw mechanism
+                       btdm8821ae.b_agc_table_en = false;
+                       btdm8821ae.b_adc_back_off_on = false;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+
+                       // fw mechanism
+                       btdm8821ae.b_ps_tdma_on = false;
+                       btdm8821ae.b_tdma_on = false;
+                       btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_OFF;
+                       btdm8821ae.b2_ant_hid_en = true;
+                       btdm8821ae.fw_dac_swing_lvl = 0x20;
+               }
+       }
+
+       if (rtl8821ae_dm_bt_need_to_dec_bt_pwr(hw)) {
+               btdm8821ae.b_dec_bt_pwr = true;
+       }
+
+       if (rtl8821ae_dm_bt_is_coexist_state_changed(hw)) {
+               rtl8821ae_dm_bt_set_bt_dm(hw, &btdm8821ae);
+       }
+}
+
+
+void rtl8821ae_dm_bt_2_ant_2_dp_action_no_profile(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct btdm_8821ae btdm8821ae;
+       u8 bt_rssi_state;
+
+       rtl8821ae_dm_bt_btdm_structure_reload(hw, &btdm8821ae);
+
+       btdm8821ae.b_rf_rx_lpf_shrink = true;
+       btdm8821ae.b_low_penalty_rate_adaptive = true;
+       btdm8821ae.b_reject_aggre_pkt = false;
+
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("HT40\n"));
+               if (rtl8821ae_dm_bt_is_wifi_up_link(hw)) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Wifi Uplink\n"));
+                       /* coex table */
+                       btdm8821ae.val_0x6c0 = 0x5a5a5a5a;
+                       btdm8821ae.val_0x6c8 = 0xcccc;
+                       btdm8821ae.val_0x6cc = 0x3;
+                       // sw mechanism
+                       btdm8821ae.b_agc_table_en = false;
+                       btdm8821ae.b_adc_back_off_on = true;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+                       // fw mechanism
+                       btdm8821ae.b_tra_tdma_on = true;
+                       btdm8821ae.b_tdma_on = true;
+                       btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_ON;
+                       btdm8821ae.b2_ant_hid_en = false;
+                       //btSpec = BTHCI_GetBTCoreSpecByProf(Adapter, BT_PROFILE_A2DP);
+                       //if(btSpec >= BT_SPEC_2_1_EDR)
+                       {
+                               btdm8821ae.wlan_act_hi = 0x10;
+                               btdm8821ae.wlan_act_lo = 0x10;
+                       }
+                       //else
+                       //{
+                               //btdm8821ae.wlanActHi = 0x20;
+                               //btdm8821ae.wlanActLo = 0x20;
+                       //}
+                       btdm8821ae.bt_retry_index = 2;
+                       btdm8821ae.fw_dac_swing_lvl = 0x18;
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Wifi Downlink\n"));
+                       // coex table
+                       btdm8821ae.val_0x6c0 = 0x5a5a5a5a;
+                       btdm8821ae.val_0x6c8 = 0xcc;
+                       btdm8821ae.val_0x6cc = 0x3;
+                       // sw mechanism
+                       btdm8821ae.b_agc_table_en = false;
+                       btdm8821ae.b_adc_back_off_on = true;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+                       // fw mechanism
+                       btdm8821ae.b_tra_tdma_on = true;
+                       btdm8821ae.b_tdma_on = true;
+                       btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_ON;
+                       btdm8821ae.b2_ant_hid_en = false;
+                       //btSpec = BTHCI_GetBTCoreSpecByProf(Adapter, BT_PROFILE_A2DP);
+                       //if(btSpec >= BT_SPEC_2_1_EDR)
+                       {
+                               btdm8821ae.wlan_act_hi = 0x10;
+                               btdm8821ae.wlan_act_lo = 0x10;
+                       }
+                       //else
+                       //{
+                       //      btdm8821ae.wlanActHi = 0x20;
+                       //      btdm8821ae.wlanActLo = 0x20;
+                       //}
+                       btdm8821ae.bt_retry_index = 2;
+                       btdm8821ae.fw_dac_swing_lvl = 0x40;
+               }
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("HT20 or Legacy\n"));
+               bt_rssi_state = rtl8821ae_dm_bt_check_coex_rssi_state(hw, 2, BT_FW_COEX_THRESH_47, 0);
+
+               if(rtl8821ae_dm_bt_is_wifi_up_link(hw))
+               {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Wifi Uplink\n"));
+                       // coex table
+                       btdm8821ae.val_0x6c0 = 0x5a5a5a5a;
+                       btdm8821ae.val_0x6c8 = 0xcccc;
+                       btdm8821ae.val_0x6cc = 0x3;
+                       // sw mechanism
+                       if( (bt_rssi_state == BT_RSSI_STATE_HIGH) ||
+                               (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH) )
+                       {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Wifi rssi high \n"));
+                               btdm8821ae.b_agc_table_en = true;
+                               btdm8821ae.b_adc_back_off_on = true;
+                               btdm8821ae.b_sw_dac_swing_on = false;
+                       } else {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Wifi rssi low \n"));
+                               btdm8821ae.b_agc_table_en = false;
+                               btdm8821ae.b_adc_back_off_on = false;
+                               btdm8821ae.b_sw_dac_swing_on = false;
+                       }
+                       // fw mechanism
+                       btdm8821ae.b_tra_tdma_on = true;
+                       btdm8821ae.b_tdma_on = true;
+                       btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_ON;
+                       btdm8821ae.b2_ant_hid_en = false;
+                       //btSpec = BTHCI_GetBTCoreSpecByProf(Adapter, BT_PROFILE_A2DP);
+                       //if(btSpec >= BT_SPEC_2_1_EDR)
+                       {
+                               btdm8821ae.wlan_act_hi = 0x10;
+                               btdm8821ae.wlan_act_lo = 0x10;
+                       }
+                       //else
+                       //{
+                               //btdm8821ae.wlanActHi = 0x20;
+                               //btdm8821ae.wlanActLo = 0x20;
+                       //}
+                       btdm8821ae.bt_retry_index = 2;
+                       btdm8821ae.fw_dac_swing_lvl = 0x18;
+               }
+               else
+               {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Wifi Downlink\n"));
+                       // coex table
+                       btdm8821ae.val_0x6c0 = 0x5a5a5a5a;
+                       btdm8821ae.val_0x6c8 = 0xcc;
+                       btdm8821ae.val_0x6cc = 0x3;
+                       // sw mechanism
+                       if( (bt_rssi_state == BT_RSSI_STATE_HIGH) ||
+                               (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH) )
+                       {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Wifi rssi high \n"));
+                               btdm8821ae.b_agc_table_en = true;
+                               btdm8821ae.b_adc_back_off_on = true;
+                               btdm8821ae.b_sw_dac_swing_on = false;
+                       }
+                       else
+                       {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("Wifi rssi low \n"));
+                               btdm8821ae.b_agc_table_en = false;
+                               btdm8821ae.b_adc_back_off_on = false;
+                               btdm8821ae.b_sw_dac_swing_on = false;
+                       }
+                       // fw mechanism
+                       btdm8821ae.b_tra_tdma_on = true;
+                       btdm8821ae.b_tdma_on = true;
+                       btdm8821ae.tdma_dac_swing = TDMA_DAC_SWING_ON;
+                       btdm8821ae.b2_ant_hid_en = false;
+                       //btSpec = BTHCI_GetBTCoreSpecByProf(Adapter, BT_PROFILE_A2DP);
+                       //if(btSpec >= BT_SPEC_2_1_EDR)
+                       {
+                               btdm8821ae.wlan_act_hi = 0x10;
+                               btdm8821ae.wlan_act_lo = 0x10;
+                       }
+                       //else
+                       //{
+                               //btdm8821ae.wlanActHi = 0x20;
+                               //btdm8821ae.wlanActLo = 0x20;
+                       //}
+                       btdm8821ae.bt_retry_index = 2;
+                       btdm8821ae.fw_dac_swing_lvl = 0x40;
+               }
+       }
+
+       if (rtl8821ae_dm_bt_need_to_dec_bt_pwr(hw)) {
+               btdm8821ae.b_dec_bt_pwr = true;
+       }
+
+       if (rtl8821ae_dm_bt_is_coexist_state_changed(hw)) {
+               rtl8821ae_dm_bt_set_bt_dm(hw, &btdm8821ae);
+       }
+}
+
+
+//============================================================
+// extern function start with BTDM_
+//============================================================
+u32 rtl8821ae_dm_bt_tx_rx_couter_h(struct ieee80211_hw *hw)
+{
+       u32     counters=0;
+
+       counters = hal_coex_8821ae.high_priority_tx + hal_coex_8821ae.high_priority_rx ;
+       return counters;
+}
+
+u32 rtl8821ae_dm_bt_tx_rx_couter_l(struct ieee80211_hw *hw)
+{
+       u32 counters=0;
+
+       counters = hal_coex_8821ae.low_priority_tx + hal_coex_8821ae.low_priority_rx ;
+       return counters;
+}
+
+u8 rtl8821ae_dm_bt_bt_tx_rx_counter_level(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       u32     bt_tx_rx_cnt = 0;
+       u8      bt_tx_rx_cnt_lvl = 0;
+
+       bt_tx_rx_cnt = rtl8821ae_dm_bt_tx_rx_couter_h(hw)
+                               + rtl8821ae_dm_bt_tx_rx_couter_l(hw);
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+               ("[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt));
+
+       rtlpcipriv->btcoexist.current_state_h &= ~\
+                (BT_COEX_STATE_BT_CNT_LEVEL_0 | BT_COEX_STATE_BT_CNT_LEVEL_1|
+                 BT_COEX_STATE_BT_CNT_LEVEL_2);
+
+       if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_3) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], BT TxRx Counters at level 3\n"));
+               bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_3;
+               rtlpcipriv->btcoexist.current_state_h |= BT_COEX_STATE_BT_CNT_LEVEL_3;
+       } else if(bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_2) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], BT TxRx Counters at level 2\n"));
+               bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_2;
+               rtlpcipriv->btcoexist.current_state_h |= BT_COEX_STATE_BT_CNT_LEVEL_2;
+       } else if(bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_1) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], BT TxRx Counters at level 1\n"));
+               bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_1;
+               rtlpcipriv->btcoexist.current_state_h  |= BT_COEX_STATE_BT_CNT_LEVEL_1;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], BT TxRx Counters at level 0\n"));
+               bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_0;
+               rtlpcipriv->btcoexist.current_state_h |= BT_COEX_STATE_BT_CNT_LEVEL_0;
+       }
+       return bt_tx_rx_cnt_lvl;
+}
+
+
+void rtl8821ae_dm_bt_2_ant_hid_sco_esco(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct btdm_8821ae btdm8821ae;
+
+       u8 bt_rssi_state, bt_rssi_state1;
+       u8      bt_tx_rx_cnt_lvl = 0;
+
+       rtl8821ae_dm_bt_btdm_structure_reload(hw, &btdm8821ae);
+
+
+       btdm8821ae.b_rf_rx_lpf_shrink = true;
+       btdm8821ae.b_low_penalty_rate_adaptive = true;
+       btdm8821ae.b_reject_aggre_pkt = false;
+
+       bt_tx_rx_cnt_lvl = rtl8821ae_dm_bt_bt_tx_rx_counter_level(hw);
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl));
+
+       if(rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
+       {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("HT40\n"));
+               // coex table
+               btdm8821ae.val_0x6c0 = 0x55555555;
+               btdm8821ae.val_0x6c8 = 0xffff;
+               btdm8821ae.val_0x6cc = 0x3;
+
+               // sw mechanism
+               btdm8821ae.b_agc_table_en = false;
+               btdm8821ae.b_adc_back_off_on = false;
+               btdm8821ae.b_sw_dac_swing_on = false;
+
+               // fw mechanism
+               btdm8821ae.b_ps_tdma_on = true;
+               if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1400\n"));
+                       btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                       btdm8821ae.ps_tdma_byte[1] = 0x5;
+                       btdm8821ae.ps_tdma_byte[2] = 0x5;
+                       btdm8821ae.ps_tdma_byte[3] = 0x2;
+                       btdm8821ae.ps_tdma_byte[4] = 0x80;
+               } else if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"));
+                       btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                       btdm8821ae.ps_tdma_byte[1] = 0xa;
+                       btdm8821ae.ps_tdma_byte[2] = 0xa;
+                       btdm8821ae.ps_tdma_byte[3] = 0x2;
+                       btdm8821ae.ps_tdma_byte[4] = 0x80;
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters < 1200\n"));
+                       btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                       btdm8821ae.ps_tdma_byte[1] = 0xf;
+                       btdm8821ae.ps_tdma_byte[2] = 0xf;
+                       btdm8821ae.ps_tdma_byte[3] = 0x2;
+                       btdm8821ae.ps_tdma_byte[4] = 0x80;
+               }
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("HT20 or Legacy\n"));
+               bt_rssi_state = rtl8821ae_dm_bt_check_coex_rssi_state(hw, 2, 47, 0);
+               bt_rssi_state1 = rtl8821ae_dm_bt_check_coex_rssi_state1(hw, 2, 27, 0);
+
+               // coex table
+               btdm8821ae.val_0x6c0 = 0x55555555;
+               btdm8821ae.val_0x6c8 = 0xffff;
+               btdm8821ae.val_0x6cc = 0x3;
+
+               // sw mechanism
+               if( (bt_rssi_state == BT_RSSI_STATE_HIGH) ||
+                       (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH) ) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi high \n"));
+                       btdm8821ae.b_agc_table_en = true;
+                       btdm8821ae.b_adc_back_off_on = true;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi low \n"));
+                       btdm8821ae.b_agc_table_en = false;
+                       btdm8821ae.b_adc_back_off_on = false;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+               }
+
+               // fw mechanism
+               btdm8821ae.b_ps_tdma_on = true;
+               if( (bt_rssi_state1 == BT_RSSI_STATE_HIGH) ||
+                       (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH) ) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,("Wifi rssi-1 high \n"));
+                       // only rssi high we need to do this,
+                       // when rssi low, the value will modified by fw
+                       rtl_write_byte(rtlpriv, 0x883, 0x40);
+                       if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0x5;
+                               btdm8821ae.ps_tdma_byte[2] = 0x5;
+                               btdm8821ae.ps_tdma_byte[3] = 0x83;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xa;
+                               btdm8821ae.ps_tdma_byte[2] = 0xa;
+                               btdm8821ae.ps_tdma_byte[3] = 0x83;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters < 1200\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xf;
+                               btdm8821ae.ps_tdma_byte[2] = 0xf;
+                               btdm8821ae.ps_tdma_byte[3] = 0x83;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       }
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi-1 low \n"));
+                       if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2)
+                       {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0x5;
+                               btdm8821ae.ps_tdma_byte[2] = 0x5;
+                               btdm8821ae.ps_tdma_byte[3] = 0x2;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xa;
+                               btdm8821ae.ps_tdma_byte[2] = 0xa;
+                               btdm8821ae.ps_tdma_byte[3] = 0x2;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters < 1200\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xf;
+                               btdm8821ae.ps_tdma_byte[2] = 0xf;
+                               btdm8821ae.ps_tdma_byte[3] = 0x2;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       }
+               }
+       }
+
+       if (rtl8821ae_dm_bt_need_to_dec_bt_pwr(hw)) {
+               btdm8821ae.b_dec_bt_pwr = true;
+       }
+
+       // Always ignore WlanAct if bHid|bSCOBusy|bSCOeSCO
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+               ("[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n",
+               hal_coex_8821ae.bt_inq_page_start_time, bt_tx_rx_cnt_lvl));
+       if( (hal_coex_8821ae.bt_inq_page_start_time) ||
+               (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl) ) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], Set BT inquiry / page scan 0x3a setting\n"));
+               btdm8821ae.b_ps_tdma_on = true;
+               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+               btdm8821ae.ps_tdma_byte[1] = 0x5;
+               btdm8821ae.ps_tdma_byte[2] = 0x5;
+               btdm8821ae.ps_tdma_byte[3] = 0x2;
+               btdm8821ae.ps_tdma_byte[4] = 0x80;
+       }
+
+       if(rtl8821ae_dm_bt_is_coexist_state_changed(hw)) {
+               rtl8821ae_dm_bt_set_bt_dm(hw, &btdm8821ae);
+       }
+}
+
+void rtl8821ae_dm_bt_2_ant_ftp_a2dp(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct btdm_8821ae btdm8821ae;
+
+       u8 bt_rssi_state, bt_rssi_state1;
+       u32 bt_tx_rx_cnt_lvl = 0;
+
+       rtl8821ae_dm_bt_btdm_structure_reload(hw, &btdm8821ae);
+
+       btdm8821ae.b_rf_rx_lpf_shrink = true;
+       btdm8821ae.b_low_penalty_rate_adaptive = true;
+       btdm8821ae.b_reject_aggre_pkt = false;
+
+       bt_tx_rx_cnt_lvl = rtl8821ae_dm_bt_bt_tx_rx_counter_level(hw);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl));
+
+       if(rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
+       {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("HT40\n"));
+               bt_rssi_state = rtl8821ae_dm_bt_check_coex_rssi_state(hw, 2, 37, 0);
+
+               // coex table
+               btdm8821ae.val_0x6c0 = 0x55555555;
+               btdm8821ae.val_0x6c8 = 0xffff;
+               btdm8821ae.val_0x6cc = 0x3;
+
+               // sw mechanism
+               btdm8821ae.b_agc_table_en = false;
+               btdm8821ae.b_adc_back_off_on = true;
+               btdm8821ae.b_sw_dac_swing_on = false;
+
+               // fw mechanism
+               btdm8821ae.b_ps_tdma_on = true;
+               if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
+                       (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH) ) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi high \n"));
+                       if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0x5;
+                               btdm8821ae.ps_tdma_byte[2] = 0x5;
+                               btdm8821ae.ps_tdma_byte[3] = 0x81;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xa;
+                               btdm8821ae.ps_tdma_byte[2] = 0xa;
+                               btdm8821ae.ps_tdma_byte[3] = 0x81;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters < 1200\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xf;
+                               btdm8821ae.ps_tdma_byte[2] = 0xf;
+                               btdm8821ae.ps_tdma_byte[3] = 0x81;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       }
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi low \n"));
+                       if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0x5;
+                               btdm8821ae.ps_tdma_byte[2] = 0x5;
+                               btdm8821ae.ps_tdma_byte[3] = 0x0;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xa;
+                               btdm8821ae.ps_tdma_byte[2] = 0xa;
+                               btdm8821ae.ps_tdma_byte[3] = 0x0;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters < 1200\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xf;
+                               btdm8821ae.ps_tdma_byte[2] = 0xf;
+                               btdm8821ae.ps_tdma_byte[3] = 0x0;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       }
+               }
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("HT20 or Legacy\n"));
+               bt_rssi_state = rtl8821ae_dm_bt_check_coex_rssi_state(hw, 2, 47, 0);
+               bt_rssi_state1 = rtl8821ae_dm_bt_check_coex_rssi_state1(hw, 2, 27, 0);
+
+               // coex table
+               btdm8821ae.val_0x6c0 = 0x55555555;
+               btdm8821ae.val_0x6c8 = 0xffff;
+               btdm8821ae.val_0x6cc = 0x3;
+
+               // sw mechanism
+               if( (bt_rssi_state == BT_RSSI_STATE_HIGH) ||
+                       (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH) ) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi high \n"));
+                       btdm8821ae.b_agc_table_en = true;
+                       btdm8821ae.b_adc_back_off_on = true;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi low \n"));
+                       btdm8821ae.b_agc_table_en = false;
+                       btdm8821ae.b_adc_back_off_on = false;
+                       btdm8821ae.b_sw_dac_swing_on = false;
+               }
+
+               // fw mechanism
+               btdm8821ae.b_ps_tdma_on = true;
+               if( (bt_rssi_state1 == BT_RSSI_STATE_HIGH) ||
+                       (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH) ) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi-1 high \n"));
+                       // only rssi high we need to do this,
+                       // when rssi low, the value will modified by fw
+                       rtl_write_byte(rtlpriv, 0x883, 0x40);
+                       if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0x5;
+                               btdm8821ae.ps_tdma_byte[2] = 0x5;
+                               btdm8821ae.ps_tdma_byte[3] = 0x81;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xa;
+                               btdm8821ae.ps_tdma_byte[2] = 0xa;
+                               btdm8821ae.ps_tdma_byte[3] = 0x81;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters < 1200\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xf;
+                               btdm8821ae.ps_tdma_byte[2] = 0xf;
+                               btdm8821ae.ps_tdma_byte[3] = 0x81;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       }
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Wifi rssi-1 low \n"));
+                       if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0x5;
+                               btdm8821ae.ps_tdma_byte[2] = 0x5;
+                               btdm8821ae.ps_tdma_byte[3] = 0x0;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else if(bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xa;
+                               btdm8821ae.ps_tdma_byte[2] = 0xa;
+                               btdm8821ae.ps_tdma_byte[3] = 0x0;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       } else {
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BT TxRx Counters < 1200\n"));
+                               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+                               btdm8821ae.ps_tdma_byte[1] = 0xf;
+                               btdm8821ae.ps_tdma_byte[2] = 0xf;
+                               btdm8821ae.ps_tdma_byte[3] = 0x0;
+                               btdm8821ae.ps_tdma_byte[4] = 0x80;
+                       }
+               }
+       }
+
+       if(rtl8821ae_dm_bt_need_to_dec_bt_pwr(hw)) {
+               btdm8821ae.b_dec_bt_pwr = true;
+       }
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+              ("[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n",
+               hal_coex_8821ae.bt_inq_page_start_time, bt_tx_rx_cnt_lvl));
+
+       if( (hal_coex_8821ae.bt_inq_page_start_time) ||
+               (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl) )
+       {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                               ("[BTCoex], Set BT inquiry / page scan 0x3a setting\n"));
+               btdm8821ae.b_ps_tdma_on = true;
+               btdm8821ae.ps_tdma_byte[0] = 0xa3;
+               btdm8821ae.ps_tdma_byte[1] = 0x5;
+               btdm8821ae.ps_tdma_byte[2] = 0x5;
+               btdm8821ae.ps_tdma_byte[3] = 0x83;
+               btdm8821ae.ps_tdma_byte[4] = 0x80;
+       }
+
+       if(rtl8821ae_dm_bt_is_coexist_state_changed(hw)){
+               rtl8821ae_dm_bt_set_bt_dm(hw, &btdm8821ae);
+       }
+}
+
+void rtl8821ae_dm_bt_inq_page_monitor(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 cur_time;
+       cur_time = jiffies;
+       if (hal_coex_8821ae.b_c2h_bt_inquiry_page) {
+               //pHalData->btcoexist.halCoex8821ae.btInquiryPageCnt++;
+               // bt inquiry or page is started.
+               if(hal_coex_8821ae.bt_inq_page_start_time == 0){
+                       rtlpcipriv->btcoexist.current_state  |= BT_COEX_STATE_BT_INQ_PAGE;
+                       hal_coex_8821ae.bt_inq_page_start_time = cur_time;
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                               ("[BTCoex], BT Inquiry/page is started at time : 0x%x \n",
+                               hal_coex_8821ae.bt_inq_page_start_time));
+               }
+       }
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+               ("[BTCoex], BT Inquiry/page started time : 0x%x, cur_time : 0x%x \n",
+               hal_coex_8821ae.bt_inq_page_start_time, cur_time));
+
+       if (hal_coex_8821ae.bt_inq_page_start_time) {
+               if ((((long)cur_time - (long)hal_coex_8821ae.bt_inq_page_start_time) / HZ) >= 10) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,  ("[BTCoex], BT Inquiry/page >= 10sec!!!"));
+                       hal_coex_8821ae.bt_inq_page_start_time = 0;
+                       rtlpcipriv->btcoexist.current_state &=~ BT_COEX_STATE_BT_INQ_PAGE;
+               }
+       }
+
+#if 0
+       if (hal_coex_8821ae.b_c2h_bt_inquiry_page) {
+               hal_coex_8821ae.b_c2h_bt_inquiry_page++;
+               // bt inquiry or page is started.
+       } if(hal_coex_8821ae.b_c2h_bt_inquiry_page) {
+               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_BT_INQ_PAGE;
+               if(hal_coex_8821ae.bt_inquiry_page_cnt >= 4)
+                       hal_coex_8821ae.bt_inquiry_page_cnt = 0;
+               hal_coex_8821ae.bt_inquiry_page_cnt++;
+       } else {
+               rtlpcipriv->btcoexist.current_state &=~ BT_COEX_STATE_BT_INQ_PAGE;
+       }
+#endif
+}
+
+void rtl8821ae_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+       rtlpcipriv->btcoexist.current_state &= ~\
+               (BT_COEX_STATE_PROFILE_HID | BT_COEX_STATE_PROFILE_A2DP|
+               BT_COEX_STATE_PROFILE_PAN | BT_COEX_STATE_PROFILE_SCO);
+
+       rtlpcipriv->btcoexist.current_state &= ~\
+               (BT_COEX_STATE_BTINFO_COMMON | BT_COEX_STATE_BTINFO_B_HID_SCOESCO|
+               BT_COEX_STATE_BTINFO_B_FTP_A2DP);
+}
+
+void _rtl8821ae_dm_bt_coexist_2_ant(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       u8 bt_retry_cnt;
+       u8 bt_info_original;
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex] Get bt info by fw!!\n"));
+
+       _rtl8821ae_dm_bt_check_wifi_state(hw);
+
+       if (hal_coex_8821ae.b_c2h_bt_info_req_sent) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                               ("[BTCoex] c2h for bt_info not rcvd yet!!\n"));
+       }
+
+       bt_retry_cnt = hal_coex_8821ae.bt_retry_cnt;
+       bt_info_original = hal_coex_8821ae.c2h_bt_info_original;
+
+       // when bt inquiry or page scan, we have to set h2c 0x25
+       // ignore wlanact for continuous 4x2secs
+       rtl8821ae_dm_bt_inq_page_monitor(hw);
+       rtl8821ae_dm_bt_reset_action_profile_state(hw);
+
+       if(rtl8821ae_dm_bt_is_2_ant_common_action(hw)) {
+               rtlpcipriv->btcoexist.bt_profile_case = BT_COEX_MECH_COMMON;
+               rtlpcipriv->btcoexist.bt_profile_action= BT_COEX_MECH_COMMON;
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("Action 2-Ant common.\n"));
+       } else {
+               if( (bt_info_original & BTINFO_B_HID) ||
+                       (bt_info_original & BTINFO_B_SCO_BUSY) ||
+                       (bt_info_original & BTINFO_B_SCO_ESCO) ) {
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_BTINFO_B_HID_SCOESCO;
+                               rtlpcipriv->btcoexist.bt_profile_case = BT_COEX_MECH_HID_SCO_ESCO;
+                               rtlpcipriv->btcoexist.bt_profile_action = BT_COEX_MECH_HID_SCO_ESCO;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BTInfo: bHid|bSCOBusy|bSCOeSCO\n"));
+                               rtl8821ae_dm_bt_2_ant_hid_sco_esco(hw);
+               } else if( (bt_info_original & BTINFO_B_FTP) ||
+                               (bt_info_original & BTINFO_B_A2DP) ) {
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_BTINFO_B_FTP_A2DP;
+                               rtlpcipriv->btcoexist.bt_profile_case = BT_COEX_MECH_FTP_A2DP;
+                               rtlpcipriv->btcoexist.bt_profile_action = BT_COEX_MECH_FTP_A2DP;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("BTInfo: bFTP|bA2DP\n"));
+                               rtl8821ae_dm_bt_2_ant_ftp_a2dp(hw);
+               } else {
+                               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_BTINFO_B_HID_SCOESCO;
+                               rtlpcipriv->btcoexist.bt_profile_case = BT_COEX_MECH_NONE;
+                               rtlpcipriv->btcoexist.bt_profile_action= BT_COEX_MECH_NONE;
+                               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], BTInfo: undefined case!!!!\n"));
+                               rtl8821ae_dm_bt_2_ant_hid_sco_esco(hw);
+               }
+       }
+}
+
+void _rtl8821ae_dm_bt_coexist_1_ant(struct ieee80211_hw *hw)
+{
+       return;
+}
+
+void rtl8821ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw)
+{
+       rtl8821ae_dm_bt_set_coex_table(hw, 0x5a5aaaaa, 0xcc, 0x3);
+       rtl8821ae_dm_bt_set_hw_pta_mode(hw, true);
+}
+
+void rtl8821ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw)
+{
+       rtl8821ae_dm_bt_set_fw_ignore_wlan_act(hw, false);
+       rtl8821ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
+       rtl8821ae_dm_bt_set_fw_2_ant_hid(hw, false, false);
+       rtl8821ae_dm_bt_set_fw_tra_tdma_ctrl(hw, false, TDMA_2ANT, TDMA_NAV_OFF);
+       rtl8821ae_dm_bt_set_fw_tdma_ctrl(hw, false, TDMA_2ANT,
+                               TDMA_NAV_OFF, TDMA_DAC_SWING_OFF);
+       rtl8821ae_dm_bt_set_fw_dac_swing_level(hw, 0);
+       rtl8821ae_dm_bt_set_fw_bt_hid_info(hw, false);
+       rtl8821ae_dm_bt_set_fw_bt_retry_index(hw, 2);
+       rtl8821ae_dm_bt_set_fw_wlan_act(hw, 0x10, 0x10);
+       rtl8821ae_dm_bt_set_fw_dec_bt_pwr(hw, false);
+}
+
+void rtl8821ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw)
+{
+       rtl8821ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF);
+       rtl8821ae_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_OFF);
+       rtl8821ae_dm_bt_reject_ap_aggregated_packet(hw, false);
+
+       rtl8821ae_dm_bt_set_sw_penalty_tx_rate_adaptive(hw,
+                                                       BT_TX_RATE_ADAPTIVE_NORMAL);
+       rtl8821ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME);
+       rtl8821ae_dm_bt_set_sw_full_time_dac_swing(hw, false, 0xc0);
+}
+
+void rtl8821ae_dm_bt_query_bt_information(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 h2c_parameter[1] = {0};
+
+       hal_coex_8821ae.b_c2h_bt_info_req_sent = true;
+
+       h2c_parameter[0] |=  BIT(0);
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+               ("Query Bt information, write 0x38=0x%x\n", h2c_parameter[0]));
+
+       rtl8821ae_fill_h2c_cmd(hw, 0x38, 1, h2c_parameter);
+}
+
+void rtl8821ae_dm_bt_bt_hw_counters_monitor(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       u32 reg_hp_tx_rx, reg_lp_tx_rx, u32_tmp;
+       u32 reg_hp_tx=0, reg_hp_rx=0, reg_lp_tx=0, reg_lp_rx=0;
+
+       reg_hp_tx_rx = REG_HIGH_PRIORITY_TXRX;
+       reg_lp_tx_rx = REG_LOW_PRIORITY_TXRX;
+
+       u32_tmp = rtl_read_dword(rtlpriv, reg_hp_tx_rx);
+       reg_hp_tx = u32_tmp & MASKLWORD;
+       reg_hp_rx = (u32_tmp & MASKHWORD)>>16;
+
+       u32_tmp = rtl_read_dword(rtlpriv, reg_lp_tx_rx);
+       reg_lp_tx = u32_tmp & MASKLWORD;
+       reg_lp_rx = (u32_tmp & MASKHWORD)>>16;
+
+       if(rtlpcipriv->btcoexist.lps_counter > 1) {
+               reg_hp_tx %= rtlpcipriv->btcoexist.lps_counter;
+               reg_hp_rx %= rtlpcipriv->btcoexist.lps_counter;
+               reg_lp_tx %= rtlpcipriv->btcoexist.lps_counter;
+               reg_lp_rx %= rtlpcipriv->btcoexist.lps_counter;
+       }
+
+       hal_coex_8821ae.high_priority_tx = reg_hp_tx;
+       hal_coex_8821ae.high_priority_rx = reg_hp_rx;
+       hal_coex_8821ae.low_priority_tx = reg_lp_tx;
+       hal_coex_8821ae.low_priority_rx = reg_lp_rx;
+
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+               ("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));
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+               ("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));
+       rtlpcipriv->btcoexist.lps_counter = 0;
+       //rtl_write_byte(rtlpriv, 0x76e, 0xc);
+}
+
+void rtl8821ae_dm_bt_bt_enable_disable_check(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       bool bt_alife = true;
+
+       if (hal_coex_8821ae.high_priority_tx == 0 &&
+               hal_coex_8821ae.high_priority_rx == 0 &&
+               hal_coex_8821ae.low_priority_tx == 0 &&
+               hal_coex_8821ae.low_priority_rx == 0) {
+               bt_alife = false;
+       }
+       if (hal_coex_8821ae.high_priority_tx == 0xeaea &&
+               hal_coex_8821ae.high_priority_rx == 0xeaea &&
+               hal_coex_8821ae.low_priority_tx == 0xeaea &&
+               hal_coex_8821ae.low_priority_rx == 0xeaea) {
+               bt_alife = false;
+       }
+       if (hal_coex_8821ae.high_priority_tx == 0xffff &&
+               hal_coex_8821ae.high_priority_rx == 0xffff &&
+               hal_coex_8821ae.low_priority_tx == 0xffff &&
+               hal_coex_8821ae.low_priority_rx == 0xffff) {
+               bt_alife = false;
+       }
+       if (bt_alife) {
+               rtlpcipriv->btcoexist.bt_active_zero_cnt = 0;
+               rtlpcipriv->btcoexist.b_cur_bt_disabled = false;
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("8821AE BT is enabled !!\n"));
+       } else {
+               rtlpcipriv->btcoexist.bt_active_zero_cnt++;
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE,
+                       ("8821AE bt all counters=0, %d times!!\n",
+                       rtlpcipriv->btcoexist.bt_active_zero_cnt));
+               if (rtlpcipriv->btcoexist.bt_active_zero_cnt >= 2) {
+                       rtlpcipriv->btcoexist.b_cur_bt_disabled = true;
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("8821AE BT is disabled !!\n"));
+               }
+       }
+       if (rtlpcipriv->btcoexist.b_pre_bt_disabled !=
+               rtlpcipriv->btcoexist.b_cur_bt_disabled) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("8821AE BT is from %s to %s!!\n",
+                       (rtlpcipriv->btcoexist.b_pre_bt_disabled ? "disabled":"enabled"),
+                       (rtlpcipriv->btcoexist.b_cur_bt_disabled ? "disabled":"enabled")));
+               rtlpcipriv->btcoexist.b_pre_bt_disabled
+                       = rtlpcipriv->btcoexist.b_cur_bt_disabled;
+       }
+}
+
+
+void rtl8821ae_dm_bt_coexist(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+       rtl8821ae_dm_bt_query_bt_information(hw);
+       rtl8821ae_dm_bt_bt_hw_counters_monitor(hw);
+       rtl8821ae_dm_bt_bt_enable_disable_check(hw);
+
+       if (rtlpcipriv->btcoexist.bt_ant_num == ANT_X2) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTCoex], 2 Ant mechanism\n"));
+               _rtl8821ae_dm_bt_coexist_2_ant(hw);
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("[BTCoex], 1 Ant mechanism\n"));
+               _rtl8821ae_dm_bt_coexist_1_ant(hw);
+       }
+
+       if (!rtl8821ae_dm_bt_is_same_coexist_state(hw)) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+                       ("[BTCoex], Coexist State[bitMap] change from 0x%x%8x to 0x%x%8x\n",
+                       rtlpcipriv->btcoexist.previous_state_h,
+                       rtlpcipriv->btcoexist.previous_state,
+                       rtlpcipriv->btcoexist.current_state_h,
+                       rtlpcipriv->btcoexist.current_state));
+               rtlpcipriv->btcoexist.previous_state
+                       = rtlpcipriv->btcoexist.current_state;
+               rtlpcipriv->btcoexist.previous_state_h
+                       = rtlpcipriv->btcoexist.current_state_h;
+       }
+}
+
+void rtl8821ae_dm_bt_parse_bt_info(struct ieee80211_hw *hw, u8 * tmp_buf, u8 len)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       u8 bt_info;
+       u8 i;
+
+       hal_coex_8821ae.b_c2h_bt_info_req_sent = false;
+       hal_coex_8821ae.bt_retry_cnt = 0;
+       for (i = 0; i < len; i++) {
+               if (i == 0) {
+                       hal_coex_8821ae.c2h_bt_info_original = tmp_buf[i];
+               } else if (i == 1) {
+                       hal_coex_8821ae.bt_retry_cnt = tmp_buf[i];
+               }
+               if(i == len-1) {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("0x%2x]", tmp_buf[i]));
+               } else {
+                       RT_TRACE(COMP_BT_COEXIST, DBG_TRACE, ("0x%2x, ", tmp_buf[i]));
+               }
+       }
+       RT_TRACE(COMP_BT_COEXIST, DBG_DMESG,
+               ("BT info bt_info (Data)= 0x%x\n",hal_coex_8821ae.c2h_bt_info_original));
+       bt_info = hal_coex_8821ae.c2h_bt_info_original;
+
+       if(bt_info & BIT(2)){
+               hal_coex_8821ae.b_c2h_bt_inquiry_page = true;
+       } else {
+               hal_coex_8821ae.b_c2h_bt_inquiry_page = false;
+       }
+
+       if (bt_info & BTINFO_B_CONNECTION) {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTC2H], BTInfo: bConnect=true\n"));
+               rtlpcipriv->btcoexist.b_bt_busy = true;
+               rtlpcipriv->btcoexist.current_state &= ~BT_COEX_STATE_BT_IDLE;
+       } else {
+               RT_TRACE(COMP_BT_COEXIST, DBG_DMESG, ("[BTC2H], BTInfo: bConnect=false\n"));
+               rtlpcipriv->btcoexist.b_bt_busy = false;
+               rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_BT_IDLE;
+       }
+}
+void rtl_8821ae_c2h_command_handle(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct c2h_evt_hdr c2h_event;
+       u8 * ptmp_buf = NULL;
+       u8 index = 0;
+       u8 u1b_tmp = 0;
+       memset(&c2h_event, 0, sizeof(c2h_event));
+       u1b_tmp = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL);
+       RT_TRACE(COMP_FW, DBG_DMESG,
+               ("&&&&&&: REG_C2HEVT_MSG_NORMAL is 0x%x\n", u1b_tmp));
+       c2h_event.cmd_id = u1b_tmp & 0xF;
+       c2h_event.cmd_len = (u1b_tmp & 0xF0) >> 4;
+       c2h_event.cmd_seq = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 1);
+       RT_TRACE(COMP_FW, DBG_DMESG, ("cmd_id: %d, cmd_len: %d, cmd_seq: %d\n",
+               c2h_event.cmd_id , c2h_event.cmd_len, c2h_event.cmd_seq));
+       u1b_tmp = rtl_read_byte(rtlpriv, 0x01AF);
+       if (u1b_tmp == C2H_EVT_HOST_CLOSE) {
+               return;
+       } else if (u1b_tmp != C2H_EVT_FW_CLOSE) {
+               rtl_write_byte(rtlpriv, 0x1AF, 0x00);
+               return;
+       }
+       ptmp_buf = (u8 *) kmalloc(c2h_event.cmd_len, GFP_KERNEL);
+       if(ptmp_buf == NULL) {
+               RT_TRACE(COMP_FW, DBG_TRACE, ("malloc cmd buf failed\n"));
+               return;
+       }
+
+       /* Read the content */
+       for (index = 0; index < c2h_event.cmd_len; index ++) {
+               ptmp_buf[index] = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 2+ index);
+       }
+
+       switch(c2h_event.cmd_id) {
+               case C2H_BT_RSSI:
+                       break;
+
+       case C2H_BT_OP_MODE:
+                       break;
+
+       case BT_INFO:
+               RT_TRACE(COMP_FW, DBG_TRACE,
+                       ("BT info Byte[0] (ID) is 0x%x\n", c2h_event.cmd_id));
+               RT_TRACE(COMP_FW, DBG_TRACE,
+                       ("BT info Byte[1] (Seq) is 0x%x\n", c2h_event.cmd_seq));
+               RT_TRACE(COMP_FW, DBG_TRACE,
+                       ("BT info Byte[2] (Data)= 0x%x\n", ptmp_buf[0]));
+
+               if (rtlpriv->cfg->ops->get_btc_status()){
+                       rtlpriv->btcoexist.btc_ops->btc_btinfo_notify(rtlpriv, ptmp_buf, c2h_event.cmd_len);
+               }
+               break;
+       default:
+               break;
+       }
+
+       if(ptmp_buf)
+               kfree(ptmp_buf);
+
+       rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE);
+}
+
+
+
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/hal_btc.h b/drivers/staging/rtl8821ae/rtl8821ae/hal_btc.h
new file mode 100644 (file)
index 0000000..a94474f
--- /dev/null
@@ -0,0 +1,160 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_HAL_BTC_H__
+#define __RTL8821AE_HAL_BTC_H__
+
+#include "../wifi.h"
+#include "btc.h"
+#include "hal_bt_coexist.h"
+
+#define        BT_TXRX_CNT_THRES_1                             1200
+#define        BT_TXRX_CNT_THRES_2                             1400
+#define        BT_TXRX_CNT_THRES_3                             3000
+#define        BT_TXRX_CNT_LEVEL_0                             0       // < 1200
+#define        BT_TXRX_CNT_LEVEL_1                             1       // >= 1200 && < 1400
+#define        BT_TXRX_CNT_LEVEL_2                             2       // >= 1400
+#define        BT_TXRX_CNT_LEVEL_3                             3
+
+
+
+#define        BT_COEX_DISABLE         0
+#define        BT_Q_PKT_OFF            0
+#define        BT_Q_PKT_ON                     1
+
+#define        BT_TX_PWR_OFF           0
+#define        BT_TX_PWR_ON            1
+
+/* TDMA mode definition */
+#define        TDMA_2ANT                       0
+#define        TDMA_1ANT                       1
+#define        TDMA_NAV_OFF            0
+#define        TDMA_NAV_ON                     1
+#define        TDMA_DAC_SWING_OFF      0
+#define        TDMA_DAC_SWING_ON       1
+
+/* PTA mode related definition */
+#define        BT_PTA_MODE_OFF         0
+#define        BT_PTA_MODE_ON          1
+
+/* Penalty Tx Rate Adaptive */
+#define        BT_TX_RATE_ADAPTIVE_NORMAL      0
+#define        BT_TX_RATE_ADAPTIVE_LOW_PENALTY 1
+
+/* RF Corner */
+#define        BT_RF_RX_LPF_CORNER_RESUME      0
+#define        BT_RF_RX_LPF_CORNER_SHRINK      1
+
+#define C2H_EVT_HOST_CLOSE             0x00
+#define C2H_EVT_FW_CLOSE               0xFF
+
+enum bt_traffic_mode {
+       BT_MOTOR_EXT_BE = 0x00,
+       BT_MOTOR_EXT_GUL = 0x01,
+       BT_MOTOR_EXT_GUB = 0x02,
+       BT_MOTOR_EXT_GULB = 0x03
+};
+
+enum bt_traffic_mode_profile {
+       BT_PROFILE_NONE,
+       BT_PROFILE_A2DP,
+       BT_PROFILE_PAN,
+       BT_PROFILE_HID,
+       BT_PROFILE_SCO
+};
+
+enum hci_ext_bt_operation {
+       HCI_BT_OP_NONE = 0x0,
+       HCI_BT_OP_INQUIRE_START = 0x1,
+       HCI_BT_OP_INQUIRE_FINISH = 0x2,
+       HCI_BT_OP_PAGING_START = 0x3,
+       HCI_BT_OP_PAGING_SUCCESS = 0x4,
+       HCI_BT_OP_PAGING_UNSUCCESS = 0x5,
+       HCI_BT_OP_PAIRING_START = 0x6,
+       HCI_BT_OP_PAIRING_FINISH = 0x7,
+       HCI_BT_OP_BT_DEV_ENABLE = 0x8,
+       HCI_BT_OP_BT_DEV_DISABLE = 0x9,
+       HCI_BT_OP_MAX,
+};
+
+enum bt_spec {
+       BT_SPEC_1_0_b = 0x00,
+       BT_SPEC_1_1 = 0x01,
+       BT_SPEC_1_2 = 0x02,
+       BT_SPEC_2_0_EDR = 0x03,
+       BT_SPEC_2_1_EDR = 0x04,
+       BT_SPEC_3_0_HS = 0x05,
+       BT_SPEC_4_0 = 0x06
+};
+
+struct c2h_evt_hdr {
+        u8 cmd_id;
+        u8 cmd_len;
+        u8 cmd_seq;
+};
+
+enum bt_state{
+       BT_INFO_STATE_DISABLED = 0,
+       BT_INFO_STATE_NO_CONNECTION = 1,
+       BT_INFO_STATE_CONNECT_IDLE = 2,
+       BT_INFO_STATE_INQ_OR_PAG = 3,
+       BT_INFO_STATE_ACL_ONLY_BUSY = 4,
+       BT_INFO_STATE_SCO_ONLY_BUSY = 5,
+       BT_INFO_STATE_ACL_SCO_BUSY = 6,
+       BT_INFO_STATE_HID_BUSY = 7,
+       BT_INFO_STATE_HID_SCO_BUSY = 8,
+       BT_INFO_STATE_MAX = 7
+};
+
+enum rtl8723be_c2h_evt {
+       C2H_DBG = 0,
+       C2H_TSF = 1,
+       C2H_AP_RPT_RSP = 2,
+       C2H_CCX_TX_RPT = 3,     // The FW notify the report of the specific tx packet.
+       C2H_BT_RSSI = 4,
+       C2H_BT_OP_MODE = 5,
+       C2H_HW_INFO_EXCH = 10,
+       C2H_C2H_H2C_TEST = 11,
+       BT_INFO = 9,
+       MAX_C2HEVENT
+};
+
+
+
+void rtl8821ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw);
+void rtl8821ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw);
+void rtl8821ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw);
+void rtl8821ae_dm_bt_coexist(struct ieee80211_hw *hw);
+void rtl8821ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, struct btdm_8821ae *p_btdm);
+void rtl_8821ae_c2h_command_handle(struct ieee80211_hw * hw);
+void rtl_8821ae_bt_wifi_media_status_notify(struct ieee80211_hw * hw, bool mstatus);
+void rtl8821ae_dm_bt_turn_off_bt_coexist_before_enter_lps(struct ieee80211_hw *hw);
+
+
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/hw.c b/drivers/staging/rtl8821ae/rtl8821ae/hw.c
new file mode 100644 (file)
index 0000000..5ed7a11
--- /dev/null
@@ -0,0 +1,3346 @@
+/******************************************************************************
+ *
+ * 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 "../wifi.h"
+#include "../efuse.h"
+#include "../base.h"
+#include "../regd.h"
+#include "../cam.h"
+#include "../ps.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "led.h"
+#include "hw.h"
+#include "pwrseqcmd.h"
+#include "pwrseq.h"
+#include "btc.h"
+#include "../btcoexist/rtl_btc.h"
+
+#define LLT_CONFIG     5
+
+static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
+
+       while (skb_queue_len(&ring->queue)) {
+               struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+               struct sk_buff *skb = __skb_dequeue(&ring->queue);
+
+               pci_unmap_single(rtlpci->pdev,
+                                le32_to_cpu(rtlpriv->cfg->ops->get_desc(
+                                (u8 *) entry, true, HW_DESC_TXBUFF_ADDR)),
+                                skb->len, PCI_DMA_TODEVICE);
+               kfree_skb(skb);
+               ring->idx = (ring->idx + 1) % ring->entries;
+       }
+
+}
+
+static void _rtl8821ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
+                                     u8 set_bits, u8 clear_bits)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpci->reg_bcn_ctrl_val |= set_bits;
+       rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
+
+       rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
+}
+
+void _rtl8821ae_stop_tx_beacon(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp1byte;
+
+       tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
+       rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
+       tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
+       tmp1byte &= ~(BIT(0));
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
+}
+
+void _rtl8821ae_resume_tx_beacon(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp1byte;
+
+       tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
+       rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
+       tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
+       tmp1byte |= BIT(0);
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
+}
+
+static void _rtl8821ae_enable_bcn_sub_func(struct ieee80211_hw *hw)
+{
+       _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(1));
+}
+
+static void _rtl8821ae_disable_bcn_sub_func(struct ieee80211_hw *hw)
+{
+       _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(1), 0);
+}
+
+static void _rtl8821ae_set_fw_clock_on(struct ieee80211_hw *hw,
+       u8 rpwm_val, bool b_need_turn_off_ckk)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool b_support_remote_wake_up;
+       u32 count = 0,isr_regaddr,content;
+       bool b_schedule_timer = b_need_turn_off_ckk;
+       rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
+                                       (u8 *) (&b_support_remote_wake_up));
+
+       if (!rtlhal->bfw_ready)
+               return;
+       if (!rtlpriv->psc.b_fw_current_inpsmode)
+               return;
+
+       while (1) {
+               spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+               if (rtlhal->bfw_clk_change_in_progress) {
+                       while (rtlhal->bfw_clk_change_in_progress) {
+                               spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+                               count++;
+                               udelay(100);
+                               if (count > 1000)
+                                       return;
+                               spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+                       }
+                       spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+               } else {
+                       rtlhal->bfw_clk_change_in_progress = false;
+                       spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+               }
+       }
+
+       if (IS_IN_LOW_POWER_STATE_8821AE(rtlhal->fw_ps_state)) {
+               rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
+                                       (u8 *) (&rpwm_val));
+               if (FW_PS_IS_ACK(rpwm_val)) {
+                       isr_regaddr = REG_HISR;
+                       content = rtl_read_dword(rtlpriv, isr_regaddr);
+                       while (!(content & IMR_CPWM) && (count < 500)) {
+                               udelay(50);
+                               count++;
+                               content = rtl_read_dword(rtlpriv, isr_regaddr);
+                       }
+
+                       if (content & IMR_CPWM) {
+                       rtl_write_word(rtlpriv,isr_regaddr, 0x0100);
+                       rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_8821AE;
+                       RT_TRACE(COMP_POWER, DBG_LOUD, ("Receive CPWM INT!!! Set pHalData->FwPSState = %X\n", rtlhal->fw_ps_state));
+                       }
+               }
+
+               spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+               rtlhal->bfw_clk_change_in_progress = false;
+               spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+               if (b_schedule_timer) {
+                       mod_timer(&rtlpriv->works.fw_clockoff_timer,
+                                 jiffies + MSECS(10));
+               }
+
+       } else  {
+               spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+               rtlhal->bfw_clk_change_in_progress = false;
+               spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+       }
+
+
+}
+
+static void _rtl8821ae_set_fw_clock_off(struct ieee80211_hw *hw,
+       u8 rpwm_val)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring;
+       enum rf_pwrstate rtstate;
+       bool b_schedule_timer = false;
+       u8 queue;
+
+       if (!rtlhal->bfw_ready)
+               return;
+       if (!rtlpriv->psc.b_fw_current_inpsmode)
+               return;
+       if (!rtlhal->ballow_sw_to_change_hwclc)
+               return;
+       rtlpriv->cfg->ops->get_hw_reg(hw,HW_VAR_RF_STATE,(u8 *)(&rtstate));
+       if (rtstate == ERFOFF ||rtlpriv->psc.inactive_pwrstate ==ERFOFF)
+               return;
+
+       for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
+               ring = &rtlpci->tx_ring[queue];
+               if (skb_queue_len(&ring->queue)) {
+                       b_schedule_timer = true;
+                       break;
+               }
+       }
+
+       if (b_schedule_timer) {
+               mod_timer(&rtlpriv->works.fw_clockoff_timer,
+                                         jiffies + MSECS(10));
+               return;
+       }
+
+       if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR_8821AE) {
+               spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+               if (!rtlhal->bfw_clk_change_in_progress) {
+                       rtlhal->bfw_clk_change_in_progress = true;
+                       spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+                       rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
+                       rtl_write_word(rtlpriv, REG_HISR, 0x0100);
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
+                               (u8 *) (&rpwm_val));
+                       spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
+                       rtlhal->bfw_clk_change_in_progress = false;
+                       spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+               } else {
+                       spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
+                       mod_timer(&rtlpriv->works.fw_clockoff_timer,
+                                         jiffies + MSECS(10));
+               }
+       }
+
+}
+
+static void _rtl8821ae_set_fw_ps_rf_on(struct ieee80211_hw *hw)
+{
+       u8 rpwm_val = 0;
+       rpwm_val |= (FW_PS_STATE_RF_OFF_8821AE | FW_PS_ACK);
+       _rtl8821ae_set_fw_clock_on(hw, rpwm_val, true);
+}
+
+static void _rtl8821ae_fwlps_leave(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool b_fw_current_inps = false;
+       u8 rpwm_val = 0,fw_pwrmode = FW_PS_ACTIVE_MODE;
+
+       if (ppsc->b_low_power_enable){
+               rpwm_val = (FW_PS_STATE_ALL_ON_8821AE|FW_PS_ACK);/* RF on */
+               _rtl8821ae_set_fw_clock_on(hw, rpwm_val, false);
+               rtlhal->ballow_sw_to_change_hwclc = false;
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
+                               (u8 *) (&fw_pwrmode));
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+                               (u8 *) (&b_fw_current_inps));
+       } else {
+               rpwm_val = FW_PS_STATE_ALL_ON_8821AE;   /* RF on */
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
+                               (u8 *) (&rpwm_val));
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
+                               (u8 *) (&fw_pwrmode));
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
+                               (u8 *) (&b_fw_current_inps));
+       }
+
+}
+
+static void _rtl8821ae_fwlps_enter(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool b_fw_current_inps = true;
+       u8 rpwm_val;
+
+       if (ppsc->b_low_power_enable){
+               rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_8821AE;   /* RF off */
+               rtlpriv->cfg->ops->set_hw_reg(hw,
+                               HW_VAR_FW_PSMODE_STATUS,
+                               (u8 *) (&b_fw_current_inps));
+               rtlpriv->cfg->ops->set_hw_reg(hw,
+                               HW_VAR_H2C_FW_PWRMODE,
+                               (u8 *) (&ppsc->fwctrl_psmode));
+               rtlhal->ballow_sw_to_change_hwclc = true;
+               _rtl8821ae_set_fw_clock_off(hw, rpwm_val);
+
+
+       } else {
+               rpwm_val = FW_PS_STATE_RF_OFF_8821AE;   /* RF off */
+               rtlpriv->cfg->ops->set_hw_reg(hw,
+                               HW_VAR_FW_PSMODE_STATUS,
+                               (u8 *) (&b_fw_current_inps));
+               rtlpriv->cfg->ops->set_hw_reg(hw,
+                               HW_VAR_H2C_FW_PWRMODE,
+                               (u8 *) (&ppsc->fwctrl_psmode));
+               rtlpriv->cfg->ops->set_hw_reg(hw,
+                               HW_VAR_SET_RPWM,
+                               (u8 *) (&rpwm_val));
+       }
+
+}
+
+void rtl8821ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+       switch (variable) {
+       case HW_VAR_ETHER_ADDR:
+               *((u32 *)(val)) = rtl_read_dword(rtlpriv, REG_MACID);
+               *((u16 *)(val+4)) = rtl_read_word(rtlpriv, REG_MACID + 4);
+               break;
+       case HW_VAR_BSSID:
+               *((u32 *)(val)) = rtl_read_dword(rtlpriv, REG_BSSID);
+               *((u16 *)(val+4)) = rtl_read_word(rtlpriv, REG_BSSID+4);
+               break;
+       case HW_VAR_MEDIA_STATUS:
+               val[0] = rtl_read_byte(rtlpriv, REG_CR+2) & 0x3;
+               break;
+       case HW_VAR_SLOT_TIME:
+               *((u8 *)(val)) = mac->slot_time;
+               break;
+       case HW_VAR_BEACON_INTERVAL:
+               *((u16 *)(val)) = rtl_read_word(rtlpriv, REG_BCN_INTERVAL);
+               break;
+       case HW_VAR_ATIM_WINDOW:
+               *((u16 *)(val)) =  rtl_read_word(rtlpriv, REG_ATIMWND);
+               break;
+       case HW_VAR_RCR:
+               *((u32 *) (val)) = rtlpci->receive_config;
+               break;
+       case HW_VAR_RF_STATE:
+               *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
+               break;
+       case HW_VAR_FWLPS_RF_ON:{
+                       enum rf_pwrstate rfState;
+                       u32 val_rcr;
+
+                       rtlpriv->cfg->ops->get_hw_reg(hw,
+                                                     HW_VAR_RF_STATE,
+                                                     (u8 *) (&rfState));
+                       if (rfState == ERFOFF) {
+                               *((bool *) (val)) = true;
+                       } else {
+                               val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
+                               val_rcr &= 0x00070000;
+                               if (val_rcr)
+                                       *((bool *) (val)) = false;
+                               else
+                                       *((bool *) (val)) = true;
+                       }
+                       break;
+               }
+       case HW_VAR_FW_PSMODE_STATUS:
+               *((bool *) (val)) = ppsc->b_fw_current_inpsmode;
+               break;
+       case HW_VAR_CORRECT_TSF:{
+                       u64 tsf;
+                       u32 *ptsf_low = (u32 *) & tsf;
+                       u32 *ptsf_high = ((u32 *) & tsf) + 1;
+
+                       *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
+                       *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
+
+                       *((u64 *) (val)) = tsf;
+
+                       break;
+               }
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process %x\n",variable));
+               break;
+       }
+}
+
+
+void rtl8821ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 idx;
+
+       switch (variable) {
+       case HW_VAR_ETHER_ADDR:{
+                       for (idx = 0; idx < ETH_ALEN; idx++) {
+                               rtl_write_byte(rtlpriv, (REG_MACID + idx),
+                                              val[idx]);
+                       }
+                       break;
+               }
+       case HW_VAR_BASIC_RATE:{
+                       u16 b_rate_cfg = ((u16 *) val)[0];
+                       u8 rate_index = 0;
+                       b_rate_cfg = b_rate_cfg & 0x15f;
+                       b_rate_cfg |= 0x01;
+                       rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
+                       rtl_write_byte(rtlpriv, REG_RRSR + 1,
+                                      (b_rate_cfg >> 8) & 0xff);
+                       while (b_rate_cfg > 0x1) {
+                               b_rate_cfg = (b_rate_cfg >> 1);
+                               rate_index++;
+                       }
+                       rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
+                                      rate_index);
+                       break;
+               }
+       case HW_VAR_BSSID:{
+                       for (idx = 0; idx < ETH_ALEN; idx++) {
+                               rtl_write_byte(rtlpriv, (REG_BSSID + idx),
+                                              val[idx]);
+                       }
+                       break;
+               }
+       case HW_VAR_SIFS:{
+                       rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
+                       rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
+
+                       rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
+                       rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
+
+                       if (!mac->ht_enable)
+                               rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
+                                              0x0e0e);
+                       else
+                               rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
+                                              *((u16 *) val));
+                       break;
+               }
+       case HW_VAR_SLOT_TIME:{
+                       u8 e_aci;
+
+                       RT_TRACE(COMP_MLME, DBG_LOUD,
+                                ("HW_VAR_SLOT_TIME %x\n", val[0]));
+
+                       rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
+
+                       for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
+                               rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                             HW_VAR_AC_PARAM,
+                                                             (u8 *) (&e_aci));
+                       }
+                       break;
+               }
+       case HW_VAR_ACK_PREAMBLE:{
+                       u8 reg_tmp;
+                       u8 short_preamble = (bool) (*(u8 *) val);
+                       reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2);
+                       if (short_preamble){
+                               reg_tmp |= BIT(1);
+                               rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
+                       } else {
+                               reg_tmp &= (~BIT(1));
+                               rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
+                       }
+                       break;
+               }
+       case HW_VAR_WPA_CONFIG:
+               rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val));
+               break;
+       case HW_VAR_AMPDU_MIN_SPACE:{
+                       u8 min_spacing_to_set;
+                       u8 sec_min_space;
+
+                       min_spacing_to_set = *((u8 *) val);
+                       if (min_spacing_to_set <= 7) {
+                               sec_min_space = 0;
+
+                               if (min_spacing_to_set < sec_min_space)
+                                       min_spacing_to_set = sec_min_space;
+
+                               mac->min_space_cfg = ((mac->min_space_cfg &
+                                                      0xf8) |
+                                                     min_spacing_to_set);
+
+                               *val = min_spacing_to_set;
+
+                               RT_TRACE(COMP_MLME, DBG_LOUD,
+                                        ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+                                         mac->min_space_cfg));
+
+                               rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
+                                              mac->min_space_cfg);
+                       }
+                       break;
+               }
+       case HW_VAR_SHORTGI_DENSITY:{
+                       u8 density_to_set;
+
+                       density_to_set = *((u8 *) val);
+                       mac->min_space_cfg |= (density_to_set << 3);
+
+                       RT_TRACE(COMP_MLME, DBG_LOUD,
+                                ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+                                 mac->min_space_cfg));
+
+                       rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
+                                      mac->min_space_cfg);
+
+                       break;
+               }
+       case HW_VAR_AMPDU_FACTOR:{
+                       u32     ampdu_len =  (*((u8 *)val));
+                       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
+                               if(ampdu_len < VHT_AGG_SIZE_128K)
+                                       ampdu_len = (0x2000 << (*((u8 *)val))) -1;
+                               else
+                                       ampdu_len = 0x1ffff;
+                       } else if(rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+                               if(ampdu_len < HT_AGG_SIZE_64K)
+                                       ampdu_len = (0x2000 << (*((u8 *)val))) -1;
+                               else
+                                       ampdu_len = 0xffff;
+                       }
+                       ampdu_len |= BIT(31);
+
+                       rtl_write_dword(rtlpriv,
+                               REG_AMPDU_MAX_LENGTH_8812, ampdu_len);
+                       break;
+               }
+       case HW_VAR_AC_PARAM:{
+                       u8 e_aci = *((u8 *) val);
+                       rtl8821ae_dm_init_edca_turbo(hw);
+
+                       if (rtlpci->acm_method != eAcmWay2_SW)
+                               rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                             HW_VAR_ACM_CTRL,
+                                                             (u8 *) (&e_aci));
+                       break;
+               }
+       case HW_VAR_ACM_CTRL:{
+                       u8 e_aci = *((u8 *) val);
+                       union aci_aifsn *p_aci_aifsn =
+                           (union aci_aifsn *)(&(mac->ac[0].aifs));
+                       u8 acm = p_aci_aifsn->f.acm;
+                       u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
+
+                       acm_ctrl =
+                           acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
+
+                       if (acm) {
+                               switch (e_aci) {
+                               case AC0_BE:
+                                       acm_ctrl |= AcmHw_BeqEn;
+                                       break;
+                               case AC2_VI:
+                                       acm_ctrl |= AcmHw_ViqEn;
+                                       break;
+                               case AC3_VO:
+                                       acm_ctrl |= AcmHw_VoqEn;
+                                       break;
+                               default:
+                                       RT_TRACE(COMP_ERR, DBG_WARNING,
+                                                ("HW_VAR_ACM_CTRL acm set "
+                                                 "failed: eACI is %d\n", acm));
+                                       break;
+                               }
+                       } else {
+                               switch (e_aci) {
+                               case AC0_BE:
+                                       acm_ctrl &= (~AcmHw_BeqEn);
+                                       break;
+                               case AC2_VI:
+                                       acm_ctrl &= (~AcmHw_ViqEn);
+                                       break;
+                               case AC3_VO:
+                                       acm_ctrl &= (~AcmHw_BeqEn);
+                                       break;
+                               default:
+                                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                                                ("switch case not process \n"));
+                                       break;
+                               }
+                       }
+
+                       RT_TRACE(COMP_QOS, DBG_TRACE,
+                                ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
+                                 "Write 0x%X\n", acm_ctrl));
+                       rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
+                       break;
+               }
+       case HW_VAR_RCR:{
+                       rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
+                       rtlpci->receive_config = ((u32 *) (val))[0];
+                       break;
+               }
+       case HW_VAR_RETRY_LIMIT:{
+                       u8 retry_limit = ((u8 *) (val))[0];
+
+                       rtl_write_word(rtlpriv, REG_RL,
+                                      retry_limit << RETRY_LIMIT_SHORT_SHIFT |
+                                      retry_limit << RETRY_LIMIT_LONG_SHIFT);
+                       break;
+               }
+       case HW_VAR_DUAL_TSF_RST:
+               rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
+               break;
+       case HW_VAR_EFUSE_BYTES:
+               rtlefuse->efuse_usedbytes = *((u16 *) val);
+               break;
+       case HW_VAR_EFUSE_USAGE:
+               rtlefuse->efuse_usedpercentage = *((u8 *) val);
+               break;
+       case HW_VAR_IO_CMD:
+               rtl8821ae_phy_set_io_cmd(hw, (*(enum io_type *)val));
+               break;
+       case HW_VAR_SET_RPWM:{
+                       u8 rpwm_val;
+
+                       rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
+                       udelay(1);
+
+                       if (rpwm_val & BIT(7)) {
+                               rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
+                                              (*(u8 *) val));
+                       } else {
+                               rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
+                                              ((*(u8 *) val) | BIT(7)));
+                       }
+
+                       break;
+               }
+       case HW_VAR_H2C_FW_PWRMODE:{
+                       rtl8821ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val));
+                       break;
+               }
+       case HW_VAR_FW_PSMODE_STATUS:
+               ppsc->b_fw_current_inpsmode = *((bool *) val);
+               break;
+
+       case HW_VAR_RESUME_CLK_ON:
+               _rtl8821ae_set_fw_ps_rf_on(hw);
+               break;
+
+       case HW_VAR_FW_LPS_ACTION:{
+               bool b_enter_fwlps = *((bool *) val);
+
+               if (b_enter_fwlps)
+                       _rtl8821ae_fwlps_enter(hw);
+                else
+                       _rtl8821ae_fwlps_leave(hw);
+
+                break;
+               }
+
+       case HW_VAR_H2C_FW_JOINBSSRPT:{
+                       u8 mstatus = (*(u8 *) val);
+                       u8 tmp_regcr, tmp_reg422,bcnvalid_reg;
+                       u8 count = 0, dlbcn_count = 0;
+                       bool b_recover = false;
+
+                       if (mstatus == RT_MEDIA_CONNECT) {
+                               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID,
+                                                             NULL);
+
+                               tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
+                               rtl_write_byte(rtlpriv, REG_CR + 1,
+                                              (tmp_regcr | BIT(0)));
+
+                               _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(3));
+                               _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(4), 0);
+
+                               tmp_reg422 =
+                                   rtl_read_byte(rtlpriv,
+                                                 REG_FWHW_TXQ_CTRL + 2);
+                               rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
+                                              tmp_reg422 & (~BIT(6)));
+                               if (tmp_reg422 & BIT(6))
+                                       b_recover = true;
+
+                               do {
+                                       bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL+2);
+                                       rtl_write_byte(rtlpriv, REG_TDECTRL+2,(bcnvalid_reg | BIT(0)));
+                                       _rtl8821ae_return_beacon_queue_skb(hw);
+
+                                       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                                               rtl8812ae_set_fw_rsvdpagepkt(hw, 0);
+                                       else
+                                               rtl8821ae_set_fw_rsvdpagepkt(hw, 0);
+                                       bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL+2);
+                                       count = 0;
+                                       while (!(bcnvalid_reg & BIT(0)) && count <20){
+                                               count++;
+                                               udelay(10);
+                                               bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL+2);
+                                       }
+                                       dlbcn_count++;
+                               } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count <5);
+
+                               if (bcnvalid_reg & BIT(0))
+                                       rtl_write_byte(rtlpriv, REG_TDECTRL+2, BIT(0));
+
+                               _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(3), 0);
+                               _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(4));
+
+                               if (b_recover) {
+                                       rtl_write_byte(rtlpriv,
+                                                      REG_FWHW_TXQ_CTRL + 2,
+                                                      tmp_reg422);
+                               }
+
+                               rtl_write_byte(rtlpriv, REG_CR + 1,
+                                              (tmp_regcr & ~(BIT(0))));
+                       }
+                       rtl8821ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
+
+                       break;
+               }
+       case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:{
+               rtl8821ae_set_p2p_ps_offload_cmd(hw, (*(u8 *) val));
+               break;
+       }
+
+       case HW_VAR_AID:{
+                       u16 u2btmp;
+                       u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
+                       u2btmp &= 0xC000;
+                       rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |
+                                               mac->assoc_id));
+
+                       break;
+               }
+       case HW_VAR_CORRECT_TSF:{
+                       u8 btype_ibss = ((u8 *) (val))[0];
+
+                       if (btype_ibss == true)
+                               _rtl8821ae_stop_tx_beacon(hw);
+
+                       _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(3));
+
+                       rtl_write_dword(rtlpriv, REG_TSFTR,
+                                       (u32) (mac->tsf & 0xffffffff));
+                       rtl_write_dword(rtlpriv, REG_TSFTR + 4,
+                                       (u32) ((mac->tsf >> 32) & 0xffffffff));
+
+                       _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(3), 0);
+
+                       if (btype_ibss == true)
+                               _rtl8821ae_resume_tx_beacon(hw);
+
+                       break;
+
+               }
+       case HW_VAR_NAV_UPPER: {
+                       u32     us_nav_upper = ((u32)*val);
+
+                       if(us_nav_upper > HAL_92C_NAV_UPPER_UNIT * 0xFF)
+                       {
+                               RT_TRACE(COMP_INIT , DBG_WARNING,
+                                       ("The setting value (0x%08X us) of NAV_UPPER"
+                                        " is larger than (%d * 0xFF)!!!\n",
+                                        us_nav_upper, HAL_92C_NAV_UPPER_UNIT));
+                               break;
+                       }
+                       rtl_write_byte(rtlpriv, REG_NAV_UPPER,
+                               ((u8)((us_nav_upper + HAL_92C_NAV_UPPER_UNIT - 1) / HAL_92C_NAV_UPPER_UNIT)));
+                       break;
+               }
+       case HW_VAR_KEEP_ALIVE: {
+                       u8 array[2];
+                       array[0] = 0xff;
+                       array[1] = *((u8 *)val);
+                       rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_KEEP_ALIVE_CTRL, 2, array);
+               }
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("switch case "
+                                                       "not process %x\n",variable));
+               break;
+       }
+}
+
+static bool _rtl8821ae_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       bool status = true;
+       long count = 0;
+       u32 value = _LLT_INIT_ADDR(address) |
+           _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
+
+       rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
+
+       do {
+               value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
+               if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
+                       break;
+
+               if (count > POLLING_LLT_THRESHOLD) {
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                                ("Failed to polling write LLT done at "
+                                 "address %d!\n", address));
+                       status = false;
+                       break;
+               }
+       } while (++count);
+
+       return status;
+}
+
+static bool _rtl8821ae_llt_table_init(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       unsigned short i;
+       u8 txpktbuf_bndy;
+       u8 maxPage;
+       bool status;
+
+       maxPage = 255;
+       txpktbuf_bndy = 0xF8;
+
+
+       rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy);
+       rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, MAX_RX_DMA_BUFFER_SIZE - 1);
+
+       rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
+
+       rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
+       rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
+
+       rtl_write_byte(rtlpriv, REG_PBP, 0x31);
+       rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
+
+       for (i = 0; i < (txpktbuf_bndy - 1); i++) {
+               status = _rtl8821ae_llt_write(hw, i, i + 1);
+               if (true != status)
+                       return status;
+       }
+
+       status = _rtl8821ae_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
+       if (true != status)
+               return status;
+
+       for (i = txpktbuf_bndy; i < maxPage; i++) {
+               status = _rtl8821ae_llt_write(hw, i, (i + 1));
+               if (true != status)
+                       return status;
+       }
+
+       status = _rtl8821ae_llt_write(hw, maxPage, txpktbuf_bndy);
+       if (true != status)
+               return status;
+
+       rtl_write_dword(rtlpriv, REG_RQPN, 0x80e70808);
+       rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
+
+       return true;
+}
+
+static void _rtl8821ae_gen_refresh_led_state(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       if (rtlpriv->rtlhal.up_first_time)
+               return;
+
+       if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                       rtl8812ae_sw_led_on(hw, pLed0);
+               else
+                       rtl8821ae_sw_led_on(hw, pLed0);
+       else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                       rtl8812ae_sw_led_on(hw, pLed0);
+               else
+                       rtl8821ae_sw_led_on(hw, pLed0);
+       else
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                       rtl8812ae_sw_led_off(hw, pLed0);
+               else
+                       rtl8821ae_sw_led_off(hw, pLed0);
+}
+
+static bool _rtl8821ae_init_mac(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       u8 bytetmp = 0;
+       u16 wordtmp = 0;
+       bool b_mac_func_enable = rtlhal->b_mac_func_enable;
+
+       rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
+
+       /*Auto Power Down to CHIP-off State*/
+       bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
+       rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
+               /* HW Power on sequence*/
+               if(!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
+                       PWR_INTF_PCI_MSK, RTL8812_NIC_ENABLE_FLOW)) {
+                               RT_TRACE(COMP_INIT,DBG_LOUD,("init 8812 MAC Fail as power on failure\n"));
+                               return false;
+               }
+       } else {
+               /* HW Power on sequence */
+               if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_A_MSK, PWR_FAB_ALL_MSK,
+                       PWR_INTF_PCI_MSK, RTL8821A_NIC_ENABLE_FLOW)){
+                       RT_TRACE(COMP_INIT,DBG_LOUD,("init 8821 MAC Fail as power on failure\n"));
+                       return false;
+               }
+       }
+
+       bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
+       rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
+
+       bytetmp = rtl_read_byte(rtlpriv, REG_CR);
+       bytetmp = 0xff;
+       rtl_write_byte(rtlpriv, REG_CR, bytetmp);
+       mdelay(2);
+
+       bytetmp |= 0x7f;
+       rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
+       mdelay(2);
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+               bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
+               if (bytetmp & BIT(0)) {
+                       bytetmp = rtl_read_byte(rtlpriv, 0x7c);
+                       bytetmp |= BIT(6);
+                       rtl_write_byte(rtlpriv, 0x7c, bytetmp);
+               }
+       }
+
+       bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
+       bytetmp &= ~BIT(4);
+       rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp);
+
+       rtl_write_word(rtlpriv, REG_CR, 0x2ff);
+
+       if (!b_mac_func_enable) {
+               if (!_rtl8821ae_llt_table_init(hw))
+                       return false;
+       }
+
+       rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
+       rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
+
+       /* Enable FW Beamformer Interrupt */
+       bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
+       rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
+
+       wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
+       wordtmp &= 0xf;
+       wordtmp |= 0xF5B1;
+       rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
+
+       rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
+       rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
+       rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
+       /*low address*/
+       rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
+                       rtlpci->tx_ring[BEACON_QUEUE].dma & DMA_BIT_MASK(32));
+       rtl_write_dword(rtlpriv, REG_MGQ_DESA,
+                       rtlpci->tx_ring[MGNT_QUEUE].dma & DMA_BIT_MASK(32));
+       rtl_write_dword(rtlpriv, REG_VOQ_DESA,
+                       rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
+       rtl_write_dword(rtlpriv, REG_VIQ_DESA,
+                       rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
+       rtl_write_dword(rtlpriv, REG_BEQ_DESA,
+                       rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
+       rtl_write_dword(rtlpriv, REG_BKQ_DESA,
+                       rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
+       rtl_write_dword(rtlpriv, REG_HQ_DESA,
+                       rtlpci->tx_ring[HIGH_QUEUE].dma & DMA_BIT_MASK(32));
+       rtl_write_dword(rtlpriv, REG_RX_DESA,
+                       rtlpci->rx_ring[RX_MPDU_QUEUE].dma & DMA_BIT_MASK(32));
+
+       rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x77);
+
+       rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
+
+       rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
+       _rtl8821ae_gen_refresh_led_state(hw);
+
+       return true;
+}
+
+static void _rtl8821ae_hw_configure(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u32 reg_rrsr;
+
+       reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+
+       rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
+       /* ARFB table 9 for 11ac 5G 2SS */
+       rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000);
+       /* ARFB table 10 for 11ac 5G 1SS */
+       rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000);
+       /* ARFB table 11 for 11ac 24G 1SS */
+       rtl_write_dword(rtlpriv, REG_ARFR2, 0x00000015);
+       rtl_write_dword(rtlpriv, REG_ARFR2 + 4, 0x003ff000);
+       /* ARFB table 12 for 11ac 24G 1SS */
+       rtl_write_dword(rtlpriv, REG_ARFR3, 0x00000015);
+       rtl_write_dword(rtlpriv, REG_ARFR3 + 4, 0xffcff000);
+       /* 0x420[7] = 0 , enable retry AMPDU in new AMPD not singal MPDU. */
+       rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00);
+       rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70);
+
+       /*Set retry limit*/
+       rtl_write_word(rtlpriv, REG_RL, 0x0707);
+
+
+       /* Set Data / Response auto rate fallack retry count*/
+       rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
+       rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
+       rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
+       rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
+
+       rtlpci->reg_bcn_ctrl_val = 0x1d;
+       rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
+
+       /* TBTT prohibit hold time. Suggested by designer TimChen. */
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1,0xff); // 8 ms
+
+       /* AGGR_BK_TIME Reg51A 0x16 */
+       rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
+
+       /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
+       rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
+
+       rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80);
+       rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
+       rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, 0x1F1F);
+}
+
+static u16 _rtl8821ae_mdio_read(struct rtl_priv *rtlpriv, u8 addr)
+{
+       u16 ret = 0;
+       u8 tmp = 0, count = 0;
+
+       rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6));
+       tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6) ;
+       count = 0;
+       while (tmp && count < 20) {
+               udelay(10);
+               tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
+               count++;
+       }
+       if (0 == tmp)
+               ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA);
+
+       return ret;
+}
+
+void _rtl8821ae_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data)
+{
+       u8 tmp = 0, count = 0;
+
+       rtl_write_word(rtlpriv, REG_MDIO_WDATA, data);
+       rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5));
+       tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5) ;
+       count = 0;
+       while (tmp && count < 20) {
+               udelay(10);
+               tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
+               count++;
+       }
+}
+
+static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
+{
+       u16 read_addr = addr & 0xfffc;
+       u8 tmp = 0, count = 0, ret = 0;
+
+       rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr);
+       rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2);
+       tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
+       count = 0;
+       while (tmp && count < 20) {
+               udelay(10);
+               tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
+               count++;
+       }
+       if (0 == tmp) {
+               read_addr = REG_DBI_RDATA + addr % 4;
+               ret = rtl_read_word(rtlpriv, read_addr);
+       }
+       return ret;
+}
+
+void _rtl8821ae_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data)
+{
+       u8 tmp = 0, count = 0;
+       u16 wrtie_addr, remainder = addr % 4;
+
+       wrtie_addr = REG_DBI_WDATA + remainder;
+       rtl_write_byte(rtlpriv, wrtie_addr, data);
+
+       wrtie_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12));
+       rtl_write_word(rtlpriv, REG_DBI_ADDR, wrtie_addr);
+
+       rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1);
+
+       tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
+       count = 0;
+       while (tmp && count < 20) {
+               udelay(10);
+               tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
+               count++;
+       }
+
+}
+
+static void _rtl8821ae_enable_aspm_back_door(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 tmp;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+               if (_rtl8821ae_mdio_read(rtlpriv, 0x04) != 0x8544)
+                       _rtl8821ae_mdio_write(rtlpriv, 0x04, 0x8544);
+
+               if (_rtl8821ae_mdio_read(rtlpriv, 0x0b) != 0x0070)
+                       _rtl8821ae_mdio_write(rtlpriv, 0x0b, 0x0070);
+       }
+
+       tmp = _rtl8821ae_dbi_read(rtlpriv, 0x70f);
+       _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7));
+
+       tmp = _rtl8821ae_dbi_read(rtlpriv, 0x719);
+       _rtl8821ae_dbi_write(rtlpriv, 0x719, tmp | BIT(3) | BIT(4));
+
+       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+       {
+               tmp  = _rtl8821ae_dbi_read(rtlpriv, 0x718);
+               _rtl8821ae_dbi_write(rtlpriv, 0x718, tmp|BIT(4));
+       }
+}
+
+void rtl8821ae_enable_hw_security_config(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 sec_reg_value;
+       u8 tmp;
+
+       RT_TRACE(COMP_INIT, DBG_DMESG,
+                ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+                 rtlpriv->sec.pairwise_enc_algorithm,
+                 rtlpriv->sec.group_enc_algorithm));
+
+       if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("not open hw encryption\n"));
+               return;
+       }
+
+       sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable;
+
+       if (rtlpriv->sec.use_defaultkey) {
+               sec_reg_value |= SCR_TxUseDK;
+               sec_reg_value |= SCR_RxUseDK;
+       }
+
+       sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
+
+       tmp = rtl_read_byte(rtlpriv, REG_CR + 1);
+       rtl_write_byte(rtlpriv, REG_CR + 1, tmp | BIT(1));
+
+       RT_TRACE(COMP_SEC, DBG_DMESG,
+                ("The SECR-value %x \n", sec_reg_value));
+
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
+
+}
+
+#if 0
+bool _rtl8821ae_check_pcie_dma_hang(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp;
+       tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL+3);
+       if (!(tmp&BIT(2))) {
+               rtl_write_byte(rtlpriv, REG_DBI_CTRL+3, tmp|BIT(2));
+               mdelay(100);
+       }
+
+       tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL+3);
+       if (tmp&BIT(0) || tmp&BIT(1)) {
+               RT_TRACE(COMP_INIT, DBG_LOUD,
+                       ("rtl8821ae_check_pcie_dma_hang(): TRUE! Reset PCIE DMA!\n"));
+               return true;
+       } else {
+               return false;
+       }
+}
+
+void _rtl8821ae_reset_pcie_interface_dma(struct ieee80211_hw *hw,
+                                                                                                       bool mac_power_on, bool watch_dog)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp;
+       bool release_mac_rx_pause;
+       u8 backup_pcie_dma_pause;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("_rtl8821ae_reset_pcie_interface_dma()\n"));
+
+       tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
+       tmp &= ~BIT(1);
+       rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
+       tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
+       tmp |= BIT2;
+       rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
+
+       tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
+       if (tmp & BIT(2)) {
+               release_mac_rx_pause = false;
+       } else {
+               rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp | BIT(2));
+               release_mac_rx_pause = true;
+       }
+       backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+1);
+       if (backup_pcie_dma_pause != 0xFF)
+               rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0xFF);
+
+       if (mac_power_on)
+               rtl_write_byte(rtlpriv, REG_CR, 0);
+
+       tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
+       tmp &= ~BIT(0);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, tmp);
+
+       tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
+       tmp |= ~BIT(0);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, tmp);
+
+       if (mac_power_on)
+               rtl_write_byte(rtlpriv, REG_CR, 0xFF);
+
+       tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL+2);
+       tmp |= BIT1;
+       rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL+2, tmp);
+
+       if (watch_dog) {
+               u32 rqpn = 0;
+               u32 rqpn_npq = 0;
+               u8 tx_page_boundary = _RQPN_Init_8812E(Adapter, &rqpn_npq, &rqpn);
+
+               if(LLT_table_init_8812(Adapter, TX_PAGE_BOUNDARY, RQPN, RQPN_NPQ) == RT_STATUS_FAILURE)
+                       return false;
+
+                       PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+                       PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
+
+                       // <1> Reset Tx descriptor
+                       Adapter->HalFunc.ResetTxDescHandler(Adapter,Adapter->NumTxDesc);
+
+                       // <2> Reset Rx descriptor
+                       Adapter->HalFunc.ResetRxDescHandler(Adapter,Adapter->NumRxDesc);
+
+                       // <3> Reset RFDs
+                       FreeRFDs( Adapter, TRUE);
+
+                       // <4> Reset TCBs
+                       FreeTCBs( Adapter, TRUE);
+
+                       // We should set all Rx desc own bit to 1 to prevent from RDU after enable Rx DMA. 2013.02.18, by tynli.
+                       PrepareAllRxDescBuffer(Adapter);
+
+                       PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
+                       PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+
+                       //
+                       // Initialize TRx DMA address.
+                       //
+                       // Because set 0x100 to 0x0 will cause the Rx descriptor address 0x340 be cleared to zero on 88EE,
+                       // we should re-initialize Rx desc. address before enable DMA. 2012.11.07. by tynli.
+                       InitTRxDescHwAddress8812AE(Adapter);
+               }
+
+               // In MAC power on state, BB and RF maybe in ON state, if we release TRx DMA here
+               // it will cause packets to be started to Tx/Rx, so we release Tx/Rx DMA later.
+               if(!bInMACPowerOn || bInWatchDog)
+               {
+                       // 8. release TRX DMA
+                       //write 0x284 bit[18] = 1'b0
+                       //write 0x301 = 0x00
+                       if(bReleaseMACRxPause)
+                       {
+                               u1Tmp = PlatformEFIORead1Byte(Adapter, REG_RXDMA_CONTROL);
+                               PlatformEFIOWrite1Byte(Adapter, REG_RXDMA_CONTROL, (u1Tmp&~BIT2));
+                       }
+                       PlatformEFIOWrite1Byte(Adapter,         REG_PCIE_CTRL_REG+1, BackUpPcieDMAPause);
+               }
+
+               if(IS_HARDWARE_TYPE_8821E(Adapter))
+               {
+                       //9. lock system register
+                       //       write 0xCC bit[2] = 1'b0
+                       u1Tmp = PlatformEFIORead1Byte(Adapter, REG_PMC_DBG_CTRL2_8723B);
+                       u1Tmp &= ~(BIT2);
+                       PlatformEFIOWrite1Byte(Adapter, REG_PMC_DBG_CTRL2_8723B, u1Tmp);
+               }
+
+               return RT_STATUS_SUCCESS;
+}
+#endif
+
+// Static MacID Mapping (cf. Used in MacIdDoStaticMapping) ----------
+#define MAC_ID_STATIC_FOR_DEFAULT_PORT                         0
+#define MAC_ID_STATIC_FOR_BROADCAST_MULTICAST          1
+#define MAC_ID_STATIC_FOR_BT_CLIENT_START                              2
+#define MAC_ID_STATIC_FOR_BT_CLIENT_END                                3
+// -----------------------------------------------------------
+
+void rtl8821ae_macid_initialize_mediastatus(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8      media_rpt[4] = {RT_MEDIA_CONNECT, 1, \
+               MAC_ID_STATIC_FOR_BROADCAST_MULTICAST, \
+               MAC_ID_STATIC_FOR_BT_CLIENT_END};
+
+       rtlpriv->cfg->ops->set_hw_reg(hw, \
+               HW_VAR_H2C_FW_MEDIASTATUSRPT, media_rpt);
+
+       RT_TRACE(COMP_INIT,DBG_LOUD, \
+               ("Initialize MacId media status: from %d to %d\n", \
+               MAC_ID_STATIC_FOR_BROADCAST_MULTICAST, \
+               MAC_ID_STATIC_FOR_BT_CLIENT_END));
+}
+
+int rtl8821ae_hw_init(struct ieee80211_hw *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));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       bool rtstatus = true;
+       int err;
+       u8 tmp_u1b;
+       u32 nav_upper = WIFI_NAV_UPPER_US;
+
+       rtlpriv->rtlhal.being_init_adapter = true;
+       rtlpriv->intf_ops->disable_aspm(hw);
+
+       /*YP wowlan not considered*/
+
+       tmp_u1b = rtl_read_byte(rtlpriv, REG_CR);
+       if (tmp_u1b!=0 && tmp_u1b != 0xEA) {
+               rtlhal->b_mac_func_enable = true;
+               RT_TRACE(COMP_INIT,DBG_LOUD,(" MAC has already power on.\n"));
+       } else {
+               rtlhal->b_mac_func_enable = false;
+               rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8821AE;
+       }
+
+/*     if (_rtl8821ae_check_pcie_dma_hang(hw)) {
+               _rtl8821ae_reset_pcie_interface_dma(hw,rtlhal->b_mac_func_enable,false);
+               rtlhal->b_mac_func_enable = false;
+       } */
+
+       rtstatus = _rtl8821ae_init_mac(hw);
+       if (rtstatus != true) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("Init MAC failed\n"));
+               err = 1;
+               return err;
+       }
+
+       tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
+       tmp_u1b &= 0x7F;
+       rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b);
+
+       err = rtl8821ae_download_fw(hw, false);
+       if (err) {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("Failed to download FW. Init HW "
+                         "without FW now..\n"));
+               err = 1;
+               rtlhal->bfw_ready = false;
+               return err;
+       } else {
+               rtlhal->bfw_ready = true;
+       }
+       rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8821AE;
+       rtlhal->bfw_clk_change_in_progress = false;
+       rtlhal->ballow_sw_to_change_hwclc = false;
+       rtlhal->last_hmeboxnum = 0;
+
+       /*SIC_Init(Adapter);
+       if(pHalData->AMPDUBurstMode)
+               PlatformEFIOWrite1Byte(Adapter,REG_AMPDU_BURST_MODE_8812,  0x7F);*/
+
+       rtl8821ae_phy_mac_config(hw);
+       /* because last function modify RCR, so we update
+        * rcr var here, or TP will unstable for receive_config
+        * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
+        * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
+       rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
+       rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
+       rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);*/
+       rtl8821ae_phy_bb_config(hw);
+
+       rtl8821ae_phy_rf_config(hw);
+
+       _rtl8821ae_hw_configure(hw);
+
+       rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
+
+       /*set wireless mode*/
+
+       rtlhal->b_mac_func_enable = true;
+
+       rtl_cam_reset_all_entry(hw);
+
+       rtl8821ae_enable_hw_security_config(hw);
+
+       ppsc->rfpwr_state = ERFON;
+
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
+       _rtl8821ae_enable_aspm_back_door(hw);
+       rtlpriv->intf_ops->enable_aspm(hw);
+
+       //rtl8821ae_bt_hw_init(hw);
+       rtlpriv->rtlhal.being_init_adapter = false;
+
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_NAV_UPPER, (u8 *)&nav_upper);
+
+       //rtl8821ae_dm_check_txpower_tracking(hw);
+       //rtl8821ae_phy_lc_calibrate(hw);
+
+       /* Release Rx DMA*/
+       tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
+       if (tmp_u1b & BIT(2)) {
+               /* Release Rx DMA if needed*/
+               tmp_u1b &= ~BIT(2);
+               rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b);
+       }
+
+       /* Release Tx/Rx PCIE DMA if*/
+       rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
+
+       rtl8821ae_dm_init(hw);
+       rtl8821ae_macid_initialize_mediastatus(hw);
+
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("rtl8821ae_hw_init() <====\n"));
+       return err;
+}
+
+static enum version_8821ae _rtl8821ae_read_chip_version(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       enum version_8821ae version = VERSION_UNKNOWN;
+       u32 value32;
+
+       value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("ReadChipVersion8812A 0xF0 = 0x%x \n", value32));
+
+
+
+       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+               rtlphy->rf_type = RF_2T2R;
+       else if(rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE)
+               rtlphy->rf_type = RF_1T1R;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("RF_Type is %x!!\n", rtlphy->rf_type));
+
+
+       if (value32 & TRP_VAUX_EN)
+       {
+               if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+               {
+                       if(rtlphy->rf_type == RF_2T2R)
+                               version = VERSION_TEST_CHIP_2T2R_8812;
+                       else
+                               version = VERSION_TEST_CHIP_1T1R_8812;
+               }
+               else
+                       version = VERSION_TEST_CHIP_8821;
+       } else {
+               if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+               {
+                       u32     rtl_id = ((value32 & CHIP_VER_RTL_MASK) >> 12) +1 ;
+
+                       if(rtlphy->rf_type == RF_2T2R)
+                               version = (enum version_8821ae)(CHIP_8812 | NORMAL_CHIP | RF_TYPE_2T2R);
+                       else
+                               version = (enum version_8821ae)(CHIP_8812 | NORMAL_CHIP);
+
+                       version = (enum version_8821ae)(version| (rtl_id << 12));
+               }
+               else if(rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE)
+               {
+                       u32     rtl_id = value32 & CHIP_VER_RTL_MASK;
+
+                       version = (enum version_8821ae)(CHIP_8821 | NORMAL_CHIP | rtl_id);
+               }
+       }
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
+                 "RF_2T2R" : "RF_1T1R"));
+
+       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE)
+       {
+               /*WL_HWROF_EN.*/
+               value32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
+               rtlphy->hw_rof_enable= ((value32 & WL_HWROF_EN) ? 1 : 0);
+       }
+
+       switch(version)
+       {
+               case VERSION_TEST_CHIP_1T1R_8812:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_TEST_CHIP_1T1R_8812.\n"));
+                       break;
+               case VERSION_TEST_CHIP_2T2R_8812:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_TEST_CHIP_2T2R_8812.\n"));
+                       break;
+               case VERSION_NORMAL_TSMC_CHIP_1T1R_8812:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_1T1R_8812.\n"));
+                       break;
+               case VERSION_NORMAL_TSMC_CHIP_2T2R_8812:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_2T2R_8812.\n"));
+                       break;
+               case VERSION_NORMAL_TSMC_CHIP_1T1R_8812_C_CUT:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_1T1R_8812 C CUT.\n"));
+                       break;
+               case VERSION_NORMAL_TSMC_CHIP_2T2R_8812_C_CUT:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_2T2R_8812 C CUT.\n"));
+                       break;
+               case VERSION_TEST_CHIP_8821:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_TEST_CHIP_8821.\n"));
+                       break;
+               case VERSION_NORMAL_TSMC_CHIP_8821:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_8821 A CUT.\n"));
+                       break;
+               case VERSION_NORMAL_TSMC_CHIP_8821_B_CUT:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_8821 B CUT.\n"));
+                       break;
+               default:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Chip Version ID: Unknow (0x%X).\n", version));
+                       break;
+       }
+
+       return version;
+}
+
+static int _rtl8821ae_set_media_status(struct ieee80211_hw *hw,
+                                    enum nl80211_iftype type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
+       enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
+       bt_msr &= 0xfc;
+
+       rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0);
+       RT_TRACE(COMP_BEACON, DBG_LOUD,
+               ("clear 0x550 when set HW_VAR_MEDIA_STATUS\n"));
+
+       if (type == NL80211_IFTYPE_UNSPECIFIED ||
+           type == NL80211_IFTYPE_STATION) {
+               _rtl8821ae_stop_tx_beacon(hw);
+               _rtl8821ae_enable_bcn_sub_func(hw);
+       } else if (type == NL80211_IFTYPE_ADHOC ||
+               type == NL80211_IFTYPE_AP) {
+               _rtl8821ae_resume_tx_beacon(hw);
+               _rtl8821ae_disable_bcn_sub_func(hw);
+       } else {
+               RT_TRACE(COMP_ERR, DBG_WARNING,("Set HW_VAR_MEDIA_STATUS: "
+                         "No such media status(%x).\n", type));
+       }
+
+       switch (type) {
+       case NL80211_IFTYPE_UNSPECIFIED:
+               bt_msr |= MSR_NOLINK;
+               ledaction = LED_CTL_LINK;
+               RT_TRACE(COMP_INIT, DBG_TRACE, ("Set Network type to NO LINK!\n"));
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               bt_msr |= MSR_ADHOC;
+               RT_TRACE(COMP_INIT, DBG_TRACE, ("Set Network type to Ad Hoc!\n"));
+               break;
+       case NL80211_IFTYPE_STATION:
+               bt_msr |= MSR_INFRA;
+               ledaction = LED_CTL_LINK;
+               RT_TRACE(COMP_INIT, DBG_TRACE, ("Set Network type to STA!\n"));
+               break;
+       case NL80211_IFTYPE_AP:
+               bt_msr |= MSR_AP;
+               RT_TRACE(COMP_INIT, DBG_TRACE, ("Set Network type to AP!\n"));
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("Network type %d not support!\n", type));
+               return 1;
+               break;
+
+       }
+
+       rtl_write_byte(rtlpriv, (MSR), bt_msr);
+       rtlpriv->cfg->ops->led_control(hw, ledaction);
+       if ((bt_msr & 0xfc) == MSR_AP)
+               rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
+       else
+               rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
+
+       return 0;
+}
+
+void rtl8821ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u32 reg_rcr = rtlpci->receive_config;
+
+       if (rtlpriv->psc.rfpwr_state != ERFON)
+               return;
+
+       if (check_bssid == true) {
+               reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+                                             (u8 *) (&reg_rcr));
+               _rtl8821ae_set_bcn_ctrl_reg(hw, 0, BIT(4));
+       } else if (check_bssid == false) {
+               reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
+               _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(4), 0);
+               rtlpriv->cfg->ops->set_hw_reg(hw,
+                       HW_VAR_RCR, (u8 *) (&reg_rcr));
+       }
+
+}
+
+int rtl8821ae_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("rtl8821ae_set_network_type!\n"));
+
+       if (_rtl8821ae_set_media_status(hw, type))
+               return -EOPNOTSUPP;
+
+       if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+               if (type != NL80211_IFTYPE_AP)
+                       rtl8821ae_set_check_bssid(hw, true);
+       } else {
+               rtl8821ae_set_check_bssid(hw, false);
+       }
+
+       return 0;
+}
+
+/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
+void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       rtl8821ae_dm_init_edca_turbo(hw);
+       switch (aci) {
+       case AC1_BK:
+               rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
+               break;
+       case AC0_BE:
+               /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */
+               break;
+       case AC2_VI:
+               rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
+               break;
+       case AC3_VO:
+               rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
+               break;
+       default:
+               RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+               break;
+       }
+}
+
+void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
+       rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
+       rtlpci->irq_enabled = true;
+       /* there are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM.
+       *So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore.
+       */
+       //rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0);
+       /*enable system interrupt*/
+       rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
+}
+
+void rtl8821ae_disable_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
+       rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
+       rtlpci->irq_enabled = false;
+       synchronize_irq(rtlpci->pdev->irq);
+}
+
+static void _rtl8821ae_poweroff_adapter(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 u1b_tmp;
+
+       rtlhal->b_mac_func_enable = false;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+       /* Combo (PCIe + USB) Card and PCIe-MF Card */
+       /* 1. Run LPS WL RFOFF flow */
+               //RT_TRACE(COMP_INIT, DBG_LOUD, ("=====>CardDisableRTL8812E,RTL8821A_NIC_LPS_ENTER_FLOW\n"));
+               rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
+                       PWR_INTF_PCI_MSK, RTL8821A_NIC_LPS_ENTER_FLOW);
+       }
+       /* 2. 0x1F[7:0] = 0 */
+       /* turn off RF */
+       //rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
+       if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
+               rtlhal->bfw_ready ) {
+               rtl8821ae_firmware_selfreset(hw);
+       }
+
+       /* Reset MCU. Suggested by Filen. */
+       u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2))));
+
+       /* g.   MCUFWDL 0x80[1:0]=0      */
+       /* reset MCU ready status */
+       rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+               /* HW card disable configuration. */
+               rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
+                       PWR_INTF_PCI_MSK, RTL8821A_NIC_DISABLE_FLOW);
+       } else {
+               /* HW card disable configuration. */
+               rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
+                       PWR_INTF_PCI_MSK, RTL8812_NIC_DISABLE_FLOW);
+       }
+
+       /* Reset MCU IO Wrapper */
+       u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
+       rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
+       u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
+       rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
+
+       /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
+       /* lock ISO/CLK/Power control register */
+       rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
+}
+
+void rtl8821ae_card_disable(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       enum nl80211_iftype opmode;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("rtl8821ae_card_disable.\n"));
+
+       mac->link_state = MAC80211_NOLINK;
+       opmode = NL80211_IFTYPE_UNSPECIFIED;
+       _rtl8821ae_set_media_status(hw, opmode);
+       if (rtlpriv->rtlhal.driver_is_goingto_unload ||
+           ppsc->rfoff_reason > RF_CHANGE_BY_PS)
+               rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+       RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+       _rtl8821ae_poweroff_adapter(hw);
+
+       /* after power off we should do iqk again */
+       rtlpriv->phy.iqk_initialized = false;
+}
+
+void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw,
+                                 u32 *p_inta, u32 *p_intb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
+       rtl_write_dword(rtlpriv, ISR, *p_inta);
+
+
+       *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1];
+       rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
+
+}
+
+
+void rtl8821ae_set_beacon_related_registers(struct ieee80211_hw *hw)
+{
+
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u16 bcn_interval, atim_window;
+
+       bcn_interval = mac->beacon_interval;
+       atim_window = 2;        /*FIX MERGE */
+       rtl8821ae_disable_interrupt(hw);
+       rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
+       rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
+       rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
+       rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
+       rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
+       rtl_write_byte(rtlpriv, 0x606, 0x30);
+       rtlpci->reg_bcn_ctrl_val |= BIT(3);
+       rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
+       rtl8821ae_enable_interrupt(hw);
+}
+
+void rtl8821ae_set_beacon_interval(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       u16 bcn_interval = mac->beacon_interval;
+
+       RT_TRACE(COMP_BEACON, DBG_DMESG,
+                ("beacon_interval:%d\n", bcn_interval));
+       rtl8821ae_disable_interrupt(hw);
+       rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
+       rtl8821ae_enable_interrupt(hw);
+}
+
+void rtl8821ae_update_interrupt_mask(struct ieee80211_hw *hw,
+                                  u32 add_msr, u32 rm_msr)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       RT_TRACE(COMP_INTR, DBG_LOUD,
+                ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+
+       if (add_msr)
+               rtlpci->irq_mask[0] |= add_msr;
+       if (rm_msr)
+               rtlpci->irq_mask[0] &= (~rm_msr);
+       rtl8821ae_disable_interrupt(hw);
+       rtl8821ae_enable_interrupt(hw);
+}
+
+static u8 _rtl8821ae_get_chnl_group(u8 chnl)
+{
+       u8 group = 0;
+
+       if (chnl <= 14) {
+               if (1 <= chnl && chnl <= 2 )
+                       group = 0;
+        else if (3 <= chnl && chnl <= 5 )
+                       group = 1;
+        else if (6 <= chnl && chnl <= 8 )
+                       group = 2;
+        else if (9 <= chnl && chnl <= 11)
+                       group = 3;
+        else /*if (12 <= chnl && chnl <= 14)*/
+                       group = 4;
+       } else {
+               if (36 <= chnl && chnl <= 42)
+                       group = 0;
+        else if (44 <= chnl && chnl <= 48)
+                       group = 1;
+        else if (50 <= chnl && chnl <= 58)
+                       group = 2;
+        else if (60 <= chnl && chnl <= 64)
+                       group = 3;
+        else if (100 <= chnl && chnl <= 106)
+                       group = 4;
+        else if (108 <= chnl && chnl <= 114)
+                       group = 5;
+        else if (116 <= chnl && chnl <= 122)
+                       group = 6;
+        else if (124 <= chnl && chnl <= 130)
+                       group = 7;
+        else if (132 <= chnl && chnl <= 138)
+                       group = 8;
+        else if (140 <= chnl && chnl <= 144)
+                       group = 9;
+        else if (149 <= chnl && chnl <= 155)
+                       group = 10;
+        else if (157 <= chnl && chnl <= 161)
+                       group = 11;
+        else if (165 <= chnl && chnl <= 171)
+                       group = 12;
+        else if (173 <= chnl && chnl <= 177)
+                       group = 13;
+               else
+                       /*RT_TRACE(COMP_EFUSE,DBG_LOUD,
+                               ("5G, Channel %d in Group not found \n",chnl));*/
+                       RT_ASSERT(!COMP_EFUSE,
+                               ("5G, Channel %d in Group not found \n",chnl));
+       }
+       return group;
+}
+
+static void _rtl8821ae_read_power_value_fromprom(struct ieee80211_hw *hw,
+       struct txpower_info_2g *pwrinfo24g,
+       struct txpower_info_5g *pwrinfo5g,
+       bool autoload_fail,
+       u8 *hwinfo)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 rfPath, eeAddr=EEPROM_TX_PWR_INX, group,TxCount=0;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("hal_ReadPowerValueFromPROM8821ae(): PROMContent[0x%x]=0x%x\n", (eeAddr+1), hwinfo[eeAddr+1]));
+       if (0xFF == hwinfo[eeAddr+1])  /*YJ,add,120316*/
+               autoload_fail = true;
+
+       if (autoload_fail)
+       {
+               RT_TRACE(COMP_INIT, DBG_LOUD, ("auto load fail : Use Default value!\n"));
+               for (rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++) {
+                       /*2.4G default value*/
+                       for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
+                               pwrinfo24g->index_cck_base[rfPath][group] =     0x2D;
+                               pwrinfo24g->index_bw40_base[rfPath][group] = 0x2D;
+                       }
+                       for (TxCount = 0;TxCount < MAX_TX_COUNT;TxCount++) {
+                               if (TxCount == 0) {
+                                       pwrinfo24g->bw20_diff[rfPath][0] = 0x02;
+                                       pwrinfo24g->ofdm_diff[rfPath][0] = 0x04;
+                               } else {
+                                       pwrinfo24g->bw20_diff[rfPath][TxCount] = 0xFE;
+                                       pwrinfo24g->bw40_diff[rfPath][TxCount] = 0xFE;
+                                       pwrinfo24g->cck_diff[rfPath][TxCount] = 0xFE;
+                                       pwrinfo24g->ofdm_diff[rfPath][TxCount] = 0xFE;
+                               }
+                       }
+                       /*5G default value*/
+                       for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++)
+                               pwrinfo5g->index_bw40_base[rfPath][group] = 0x2A;
+
+                       for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
+                               if (TxCount == 0) {
+                                       pwrinfo5g->ofdm_diff[rfPath][0] = 0x04;
+                                       pwrinfo5g->bw20_diff[rfPath][0] = 0x00;
+                                       pwrinfo5g->bw80_diff[rfPath][0] = 0xFE;
+                                       pwrinfo5g->bw160_diff[rfPath][0] = 0xFE;
+                               } else {
+                                       pwrinfo5g->ofdm_diff[rfPath][0] = 0xFE;
+                                       pwrinfo5g->bw20_diff[rfPath][0] = 0xFE;
+                                       pwrinfo5g->bw40_diff[rfPath][0] = 0xFE;
+                                       pwrinfo5g->bw80_diff[rfPath][0] = 0xFE;
+                                       pwrinfo5g->bw160_diff[rfPath][0] = 0xFE;
+                               }
+                       }
+               }
+               return;
+       }
+
+       rtl_priv(hw)->efuse.b_txpwr_fromeprom = true;
+
+       for (rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++) {
+               /*2.4G default value*/
+               for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
+                       pwrinfo24g->index_cck_base[rfPath][group] = hwinfo[eeAddr++];
+                       if (pwrinfo24g->index_cck_base[rfPath][group] == 0xFF)
+                               pwrinfo24g->index_cck_base[rfPath][group] = 0x2D;
+               }
+               for (group = 0 ; group < MAX_CHNL_GROUP_24G - 1; group++) {
+                       pwrinfo24g->index_bw40_base[rfPath][group] = hwinfo[eeAddr++];
+                       if (pwrinfo24g->index_bw40_base[rfPath][group] == 0xFF)
+                               pwrinfo24g->index_bw40_base[rfPath][group] = 0x2D;
+               }
+               for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount ++) {
+                       if (TxCount == 0) {
+                               pwrinfo24g->bw40_diff[rfPath][TxCount] = 0;
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo24g->bw20_diff[rfPath][TxCount] = 0x02;
+                               } else {
+                                       pwrinfo24g->bw20_diff[rfPath][TxCount] = (hwinfo[eeAddr] & 0xf0) >> 4;
+                                       if (pwrinfo24g->bw20_diff[rfPath][TxCount] & BIT(3))    /*bit sign number to 8 bit sign number*/
+                                               pwrinfo24g->bw20_diff[rfPath][TxCount] |= 0xF0;
+                               }
+
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo24g->ofdm_diff[rfPath][TxCount] = 0x04;
+                               } else {
+                                       pwrinfo24g->ofdm_diff[rfPath][TxCount] = (hwinfo[eeAddr] & 0x0f);
+                                       if(pwrinfo24g->ofdm_diff[rfPath][TxCount] & BIT(3))             /*bit sign number to 8 bit sign number*/
+                                               pwrinfo24g->ofdm_diff[rfPath][TxCount] |= 0xF0;
+                               }
+                               pwrinfo24g->cck_diff[rfPath][TxCount] = 0;
+                               eeAddr++;
+                       } else {
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo24g->bw40_diff[rfPath][TxCount] = 0xFE;
+                               } else {
+                                       pwrinfo24g->bw40_diff[rfPath][TxCount] = (hwinfo[eeAddr]&0xf0) >> 4;
+                                       if (pwrinfo24g->bw40_diff[rfPath][TxCount] & BIT(3))
+                                               pwrinfo24g->bw40_diff[rfPath][TxCount] |= 0xF0;
+                               }
+
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo24g->bw20_diff[rfPath][TxCount] = 0xFE;
+                               } else {
+                                       pwrinfo24g->bw20_diff[rfPath][TxCount] = (hwinfo[eeAddr] & 0x0f);
+                                       if (pwrinfo24g->bw20_diff[rfPath][TxCount] & BIT(3))
+                                               pwrinfo24g->bw20_diff[rfPath][TxCount] |= 0xF0;
+                               }
+
+                               eeAddr++;
+
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo24g->ofdm_diff[rfPath][TxCount] = 0xFE;
+                               } else {
+                                       pwrinfo24g->ofdm_diff[rfPath][TxCount] = (hwinfo[eeAddr] & 0xf0) >> 4;
+                                       if(pwrinfo24g->ofdm_diff[rfPath][TxCount] & BIT(3))
+                                               pwrinfo24g->ofdm_diff[rfPath][TxCount] |= 0xF0;
+                               }
+
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo24g->cck_diff[rfPath][TxCount] = 0xFE;
+                               } else {
+                                       pwrinfo24g->cck_diff[rfPath][TxCount] = (hwinfo[eeAddr] & 0x0f);
+                                       if(pwrinfo24g->cck_diff[rfPath][TxCount] & BIT(3))
+                                               pwrinfo24g->cck_diff[rfPath][TxCount] |= 0xF0;
+                               }
+                               eeAddr++;
+                       }
+               }
+
+               /*5G default value*/
+               for (group = 0 ; group < MAX_CHNL_GROUP_5G; group ++) {
+                       pwrinfo5g->index_bw40_base[rfPath][group] = hwinfo[eeAddr++];
+                       if (pwrinfo5g->index_bw40_base[rfPath][group] == 0xFF)
+                               pwrinfo5g->index_bw40_base[rfPath][group] = 0xFE;
+               }
+
+               for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
+                       if (TxCount == 0) {
+                               pwrinfo5g->bw40_diff[rfPath][TxCount] = 0;
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo5g->bw20_diff[rfPath][TxCount] = 0x0;
+                               } else {
+                                       pwrinfo5g->bw20_diff[rfPath][0] = (hwinfo[eeAddr] & 0xf0) >> 4;
+                                       if(pwrinfo5g->bw20_diff[rfPath][TxCount] & BIT(3))
+                                               pwrinfo5g->bw20_diff[rfPath][TxCount] |= 0xF0;
+                               }
+
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo5g->ofdm_diff[rfPath][TxCount] = 0x4;
+                               } else {
+                                       pwrinfo5g->ofdm_diff[rfPath][0] = (hwinfo[eeAddr] & 0x0f);
+                                       if(pwrinfo5g->ofdm_diff[rfPath][TxCount] & BIT(3))
+                                               pwrinfo5g->ofdm_diff[rfPath][TxCount] |= 0xF0;
+                               }
+                               eeAddr++;
+                       } else {
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo5g->bw40_diff[rfPath][TxCount] = 0xFE;
+                               } else {
+                                       pwrinfo5g->bw40_diff[rfPath][TxCount]= (hwinfo[eeAddr] & 0xf0) >> 4;
+                                       if(pwrinfo5g->bw40_diff[rfPath][TxCount] & BIT(3))
+                                               pwrinfo5g->bw40_diff[rfPath][TxCount] |= 0xF0;
+                               }
+
+                               if (hwinfo[eeAddr] == 0xFF) {
+                                       pwrinfo5g->bw20_diff[rfPath][TxCount] = 0xFE;
+                               } else {
+                                       pwrinfo5g->bw20_diff[rfPath][TxCount] = (hwinfo[eeAddr] & 0x0f);
+                                       if(pwrinfo5g->bw20_diff[rfPath][TxCount] & BIT(3))
+                                               pwrinfo5g->bw20_diff[rfPath][TxCount] |= 0xF0;
+                               }
+                               eeAddr++;
+                       }
+               }
+
+               if (hwinfo[eeAddr] == 0xFF) {
+                       pwrinfo5g->ofdm_diff[rfPath][1] = 0xFE;
+                       pwrinfo5g->ofdm_diff[rfPath][2] = 0xFE;
+               } else {
+                       pwrinfo5g->ofdm_diff[rfPath][1] =       (hwinfo[eeAddr] & 0xf0) >> 4;
+                       pwrinfo5g->ofdm_diff[rfPath][2] =       (hwinfo[eeAddr] & 0x0f);
+               }
+               eeAddr++;
+               if (hwinfo[eeAddr] == 0xFF)
+                       pwrinfo5g->ofdm_diff[rfPath][3] = 0xFE;
+               else
+                       pwrinfo5g->ofdm_diff[rfPath][3] = (hwinfo[eeAddr] & 0x0f);
+
+               eeAddr++;
+
+               for (TxCount = 1; TxCount < MAX_TX_COUNT; TxCount++) {
+                       if (pwrinfo5g->ofdm_diff[rfPath][TxCount] == 0xFF)
+                               pwrinfo5g->ofdm_diff[rfPath][TxCount] = 0xFE;
+                       else if(pwrinfo5g->ofdm_diff[rfPath][TxCount] & BIT(3))
+                               pwrinfo5g->ofdm_diff[rfPath][TxCount] |= 0xF0;
+               }
+               for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
+                       if (hwinfo[eeAddr] == 0xFF) {
+                               pwrinfo5g->bw80_diff[rfPath][TxCount] = 0xFE;
+                       } else {
+                               pwrinfo5g->bw80_diff[rfPath][TxCount] = (hwinfo[eeAddr] & 0xf0) >> 4;
+                               if(pwrinfo5g->bw80_diff[rfPath][TxCount] & BIT(3))              //4bit sign number to 8 bit sign number
+                                       pwrinfo5g->bw80_diff[rfPath][TxCount] |= 0xF0;
+                       }
+
+                       if (hwinfo[eeAddr] == 0xFF) {
+                               pwrinfo5g->bw160_diff[rfPath][TxCount] = 0xFE;
+                       } else {
+                               pwrinfo5g->bw160_diff[rfPath][TxCount]= (hwinfo[eeAddr] & 0x0f);
+                               if(pwrinfo5g->bw160_diff[rfPath][TxCount] & BIT(3))             //4bit sign number to 8 bit sign number
+                                       pwrinfo5g->bw160_diff[rfPath][TxCount] |= 0xF0;
+                       }
+                       eeAddr++;
+               }
+       }
+}
+
+static void _rtl8812ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
+                                                bool autoload_fail,
+                                                u8 *hwinfo)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct txpower_info_2g pwrinfo24g;
+       struct txpower_info_5g pwrinfo5g;
+       u8 channel5g[CHANNEL_MAX_NUMBER_5G] =
+                                {36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,100,102,104,106,108,110,112,
+                          114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,149,151,
+                          153,155,157,159,161,163,165,167,168,169,171,173,175,177};
+       u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, 138, 155, 171};
+       u8 rf_path, index;
+       u8 i;
+
+       _rtl8821ae_read_power_value_fromprom(hw, &pwrinfo24g, &pwrinfo5g, autoload_fail, hwinfo);
+
+       for (rf_path = 0; rf_path < 2; rf_path++) {
+               for (i = 0; i < CHANNEL_MAX_NUMBER_2G; i++) {
+                       index = _rtl8821ae_get_chnl_group(i + 1);
+
+                       if (i == CHANNEL_MAX_NUMBER_2G - 1) {
+                               rtlefuse->txpwrlevel_cck[rf_path][i] =
+                                       pwrinfo24g.index_cck_base[rf_path][5];
+                               rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
+                                       pwrinfo24g.index_bw40_base[rf_path][index];
+                       } else {
+                               rtlefuse->txpwrlevel_cck[rf_path][i] =
+                                       pwrinfo24g.index_cck_base[rf_path][index];
+                               rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
+                                       pwrinfo24g.index_bw40_base[rf_path][index];
+                       }
+               }
+
+               for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) {
+                       index = _rtl8821ae_get_chnl_group(channel5g[i]);
+                       rtlefuse->txpwr_5g_bw40base[rf_path][i] = pwrinfo5g.index_bw40_base[rf_path][index];
+               }
+               for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) {
+                       u8 upper, lower;
+                       index = _rtl8821ae_get_chnl_group(channel5g_80m[i]);
+                       upper = pwrinfo5g.index_bw40_base[rf_path][index];
+                       lower = pwrinfo5g.index_bw40_base[rf_path][index + 1];
+
+                       rtlefuse->txpwr_5g_bw80base[rf_path][i] = (upper + lower) / 2;
+               }
+               for (i = 0; i < MAX_TX_COUNT; i++) {
+                       rtlefuse->txpwr_cckdiff[rf_path][i] = pwrinfo24g.cck_diff[rf_path][i];
+                       rtlefuse->txpwr_legacyhtdiff[rf_path][i] = pwrinfo24g.ofdm_diff[rf_path][i];
+                       rtlefuse->txpwr_ht20diff[rf_path][i] = pwrinfo24g.bw20_diff[rf_path][i];
+                       rtlefuse->txpwr_ht40diff[rf_path][i] = pwrinfo24g.bw40_diff[rf_path][i];
+
+                       rtlefuse->txpwr_5g_ofdmdiff[rf_path][i] = pwrinfo5g.ofdm_diff[rf_path][i];
+                       rtlefuse->txpwr_5g_bw20diff[rf_path][i] = pwrinfo5g.bw20_diff[rf_path][i];
+                       rtlefuse->txpwr_5g_bw40diff[rf_path][i] = pwrinfo5g.bw40_diff[rf_path][i];
+                       rtlefuse->txpwr_5g_bw80diff[rf_path][i] = pwrinfo5g.bw80_diff[rf_path][i];
+               }
+       }
+
+       if (!autoload_fail){
+               rtlefuse->eeprom_regulatory =
+                       hwinfo[EEPROM_RF_BOARD_OPTION] & 0x07;/*bit0~2*/
+               if (hwinfo[EEPROM_RF_BOARD_OPTION] == 0xFF)
+                       rtlefuse->eeprom_regulatory = 0;
+       } else {
+               rtlefuse->eeprom_regulatory = 0;
+       }
+
+       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+       ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory ));
+}
+
+static void _rtl8821ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
+                                                bool autoload_fail,
+                                                u8 *hwinfo)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct txpower_info_2g pwrinfo24g;
+       struct txpower_info_5g pwrinfo5g;
+       u8 channel5g[CHANNEL_MAX_NUMBER_5G] =
+                               {36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,100,102,104,106,108,110,112,
+                 114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,149,151,
+                 153,155,157,159,161,163,165,167,168,169,171,173,175,177};
+       u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, 138, 155, 171};
+       u8 rf_path, index;
+       u8 i;
+
+       _rtl8821ae_read_power_value_fromprom(hw, &pwrinfo24g, &pwrinfo5g, autoload_fail, hwinfo);
+
+       for (rf_path = 0; rf_path < 2; rf_path++) {
+               for (i = 0; i < CHANNEL_MAX_NUMBER_2G; i++) {
+                       index = _rtl8821ae_get_chnl_group(i + 1);
+
+                       if (i == CHANNEL_MAX_NUMBER_2G - 1) {
+                               rtlefuse->txpwrlevel_cck[rf_path][i] = pwrinfo24g.index_cck_base[rf_path][5];
+                               rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = pwrinfo24g.index_bw40_base[rf_path][index];
+                       } else {
+                               rtlefuse->txpwrlevel_cck[rf_path][i] = pwrinfo24g.index_cck_base[rf_path][index];
+                               rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = pwrinfo24g.index_bw40_base[rf_path][index];
+                       }
+               }
+
+               for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) {
+                       index = _rtl8821ae_get_chnl_group(channel5g[i]);
+                       rtlefuse->txpwr_5g_bw40base[rf_path][i] = pwrinfo5g.index_bw40_base[rf_path][index];
+               }
+               for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) {
+                       u8 upper, lower;
+                       index = _rtl8821ae_get_chnl_group(channel5g_80m[i]);
+                       upper = pwrinfo5g.index_bw40_base[rf_path][index];
+                       lower = pwrinfo5g.index_bw40_base[rf_path][index + 1];
+
+                       rtlefuse->txpwr_5g_bw80base[rf_path][i] = (upper + lower) / 2;
+               }
+               for (i = 0; i < MAX_TX_COUNT; i++) {
+                       rtlefuse->txpwr_cckdiff[rf_path][i] = pwrinfo24g.cck_diff[rf_path][i];
+                       rtlefuse->txpwr_legacyhtdiff[rf_path][i] = pwrinfo24g.ofdm_diff[rf_path][i];
+                       rtlefuse->txpwr_ht20diff[rf_path][i] = pwrinfo24g.bw20_diff[rf_path][i];
+                       rtlefuse->txpwr_ht40diff[rf_path][i] = pwrinfo24g.bw40_diff[rf_path][i];
+
+                       rtlefuse->txpwr_5g_ofdmdiff[rf_path][i] = pwrinfo5g.ofdm_diff[rf_path][i];
+                       rtlefuse->txpwr_5g_bw20diff[rf_path][i] = pwrinfo5g.bw20_diff[rf_path][i];
+                       rtlefuse->txpwr_5g_bw40diff[rf_path][i] = pwrinfo5g.bw40_diff[rf_path][i];
+                       rtlefuse->txpwr_5g_bw80diff[rf_path][i] = pwrinfo5g.bw80_diff[rf_path][i];
+               }
+       }
+
+       if (!autoload_fail){
+               rtlefuse->eeprom_regulatory = hwinfo[EEPROM_RF_BOARD_OPTION] & 0x07;/*bit0~2*/
+               if (hwinfo[EEPROM_RF_BOARD_OPTION] == 0xFF)
+                       rtlefuse->eeprom_regulatory = 0;
+       } else {
+               rtlefuse->eeprom_regulatory = 0;
+       }
+
+       RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+       ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory ));
+}
+
+static void _rtl8812ae_read_adapter_info(struct ieee80211_hw *hw, bool b_pseudo_test )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       u16 i, usvalue;
+       u8 hwinfo[HWSET_MAX_SIZE];
+       u16 eeprom_id;
+
+       if (b_pseudo_test) {
+               /* need add */
+       }
+
+       if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
+               rtl_efuse_shadow_map_update(hw);
+               memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+                      HWSET_MAX_SIZE);
+       } else if (rtlefuse->epromtype == EEPROM_93C46) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("RTL819X Not boot from eeprom, check it !!"));
+       }
+
+       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP \n"),
+                     hwinfo, HWSET_MAX_SIZE);
+
+       eeprom_id = *((u16 *) & hwinfo[0]);
+       if (eeprom_id != RTL_EEPROM_ID) {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+               rtlefuse->autoload_failflag = true;
+       } else {
+               RT_TRACE(COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               rtlefuse->autoload_failflag = false;
+       }
+
+       if (rtlefuse->autoload_failflag == true) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("RTL8812AE autoload_failflag, check it !!"));
+               return;
+       }
+
+       rtlefuse->eeprom_version = *(u8 *) & hwinfo[EEPROM_VERSION];
+       if (rtlefuse->eeprom_version == 0xff)
+                       rtlefuse->eeprom_version = 0;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM version: 0x%2x\n", rtlefuse->eeprom_version));
+
+       rtlefuse->eeprom_vid = *(u16 *) &hwinfo[EEPROM_VID];
+       rtlefuse->eeprom_did = *(u16 *) &hwinfo[EEPROM_DID];
+       rtlefuse->eeprom_svid = *(u16 *) &hwinfo[EEPROM_SVID];
+       rtlefuse->eeprom_smid = *(u16 *) &hwinfo[EEPROM_SMID];
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROMId = 0x%4x\n", eeprom_id));
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+
+       /*customer ID*/
+       rtlefuse->eeprom_oemid = *(u8 *) & hwinfo[EEPROM_CUSTOMER_ID];
+       if (rtlefuse->eeprom_oemid == 0xFF)
+               rtlefuse->eeprom_oemid = 0;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+
+       for (i = 0; i < 6; i += 2) {
+               usvalue = *(u16 *) & hwinfo[EEPROM_MAC_ADDR + i];
+               *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
+       }
+
+       RT_TRACE(COMP_INIT, DBG_DMESG,
+                ("dev_addr: %pM\n", rtlefuse->dev_addr));
+
+       _rtl8812ae_read_txpower_info_from_hwpg(hw,
+               rtlefuse->autoload_failflag, hwinfo);
+
+       /*board type*/
+       rtlefuse->board_type = (((*(u8 *) & hwinfo[EEPROM_RF_BOARD_OPTION]) & 0xE0 ) >> 5);
+       if ((*(u8 *) & hwinfo[EEPROM_RF_BOARD_OPTION]) == 0xff )
+               rtlefuse->board_type = 0;
+       rtlhal->boad_type = rtlefuse->board_type;
+
+       rtl8812ae_read_bt_coexist_info_from_hwpg(hw,
+                       rtlefuse->autoload_failflag, hwinfo);
+
+       rtlefuse->eeprom_channelplan = *(u8 *) & hwinfo[EEPROM_CHANNELPLAN];
+       if (rtlefuse->eeprom_channelplan == 0xff)
+               rtlefuse->eeprom_channelplan = 0x7F;
+
+       /* set channel paln to world wide 13 */
+       //rtlefuse->channel_plan = (u8) rtlefuse->eeprom_channelplan;
+
+       /*parse xtal*/
+       rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8821AE];
+       if ( rtlefuse->crystalcap == 0xFF )
+               rtlefuse->crystalcap = 0x20;
+
+       rtlefuse->eeprom_thermalmeter = *(u8 *) & hwinfo[EEPROM_THERMAL_METER];
+       if ((rtlefuse->eeprom_thermalmeter == 0xff) ||rtlefuse->autoload_failflag )
+       {
+               rtlefuse->b_apk_thermalmeterignore = true;
+               rtlefuse->eeprom_thermalmeter = 0xff;
+       }
+
+       rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+
+       if (rtlefuse->autoload_failflag == false) {
+               rtlefuse->antenna_div_cfg = *(u8 *) & hwinfo[EEPROM_RF_BOARD_OPTION] & 0x18 >> 3;
+               if (*(u8 *) & hwinfo[EEPROM_RF_BOARD_OPTION] == 0xff)
+                       rtlefuse->antenna_div_cfg = 0x00;
+               /*if (BT_1ant())
+                       rtlefuse->antenna_div_cfg = 0;*/
+               rtlefuse->antenna_div_type = *(u8 *) & hwinfo[EEPROM_RF_ANTENNA_OPT_88E];
+               if (rtlefuse->antenna_div_type == 0xFF)
+               {
+                       rtlefuse->antenna_div_type = FIXED_HW_ANTDIV;
+               }
+       } else {
+               rtlefuse->antenna_div_cfg = 0;
+               rtlefuse->antenna_div_type = 0;
+       }
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+               ("SWAS: bHwAntDiv = %x, TRxAntDivType = %x\n",
+                rtlefuse->antenna_div_cfg, rtlefuse->antenna_div_type));
+
+       /*Hal_ReadPAType_8821A()*/
+       /*Hal_EfuseParseRateIndicationOption8821A()*/
+       /*Hal_ReadEfusePCIeCap8821AE()*/
+
+       pcipriv->ledctl.bled_opendrain = true;
+
+       if (rtlhal->oem_id == RT_CID_DEFAULT) {
+               switch (rtlefuse->eeprom_oemid) {
+               case RT_CID_DEFAULT:
+                       break;
+               case EEPROM_CID_TOSHIBA:
+                       rtlhal->oem_id = RT_CID_TOSHIBA;
+                       break;
+               case EEPROM_CID_CCX:
+                       rtlhal->oem_id = RT_CID_CCX;
+                       break;
+               case EEPROM_CID_QMI:
+                       rtlhal->oem_id = RT_CID_819x_QMI;
+                       break;
+               case EEPROM_CID_WHQL:
+                       break;
+               default:
+                       break;
+
+               }
+       }
+}
+
+static void _rtl8821ae_read_adapter_info(struct ieee80211_hw *hw, bool b_pseudo_test )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       u16 i, usvalue;
+       u8 hwinfo[HWSET_MAX_SIZE];
+       u16 eeprom_id;
+
+       if (b_pseudo_test) {
+               /* need add */
+       }
+
+       if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
+               rtl_efuse_shadow_map_update(hw);
+               memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+                      HWSET_MAX_SIZE);
+       } else if (rtlefuse->epromtype == EEPROM_93C46) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("RTL819X Not boot from eeprom, check it !!"));
+       }
+
+       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP \n"),
+                     hwinfo, HWSET_MAX_SIZE);
+
+       eeprom_id = *((u16 *) & hwinfo[0]);
+       if (eeprom_id != RTL_EEPROM_ID) {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+               rtlefuse->autoload_failflag = true;
+       } else {
+               RT_TRACE(COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               rtlefuse->autoload_failflag = false;
+       }
+
+       if (rtlefuse->autoload_failflag == true) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("RTL8812AE autoload_failflag, check it !!"));
+               return;
+       }
+
+       rtlefuse->eeprom_version = *(u8 *) & hwinfo[EEPROM_VERSION];
+       if (rtlefuse->eeprom_version == 0xff)
+                       rtlefuse->eeprom_version = 0;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM version: 0x%2x\n", rtlefuse->eeprom_version));
+
+       rtlefuse->eeprom_vid = *(u16 *) &hwinfo[EEPROM_VID];
+       rtlefuse->eeprom_did = *(u16 *) &hwinfo[EEPROM_DID];
+       rtlefuse->eeprom_svid = *(u16 *) &hwinfo[EEPROM_SVID];
+       rtlefuse->eeprom_smid = *(u16 *) &hwinfo[EEPROM_SMID];
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROMId = 0x%4x\n", eeprom_id));
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+
+       /*customer ID*/
+       rtlefuse->eeprom_oemid = *(u8 *) & hwinfo[EEPROM_CUSTOMER_ID];
+       if (rtlefuse->eeprom_oemid == 0xFF)
+               rtlefuse->eeprom_oemid = 0;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+
+       for (i = 0; i < 6; i += 2) {
+               usvalue = *(u16 *) & hwinfo[EEPROM_MAC_ADDR + i];
+               *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
+       }
+
+       RT_TRACE(COMP_INIT, DBG_DMESG,
+                ("dev_addr: %pM\n", rtlefuse->dev_addr));
+
+       _rtl8821ae_read_txpower_info_from_hwpg(hw,
+               rtlefuse->autoload_failflag, hwinfo);
+
+       /*board type*/
+       rtlefuse->board_type = (((*(u8 *) & hwinfo[EEPROM_RF_BOARD_OPTION]) & 0xE0 ) >> 5);
+       if ((*(u8 *) & hwinfo[EEPROM_RF_BOARD_OPTION]) == 0xff )
+               rtlefuse->board_type = 0;
+       rtlhal->boad_type = rtlefuse->board_type;
+
+       rtl8821ae_read_bt_coexist_info_from_hwpg(hw,
+                       rtlefuse->autoload_failflag, hwinfo);
+
+       rtlefuse->eeprom_channelplan = *(u8 *) & hwinfo[EEPROM_CHANNELPLAN];
+       if (rtlefuse->eeprom_channelplan == 0xff)
+               rtlefuse->eeprom_channelplan = 0x7F;
+
+       /* set channel paln to world wide 13 */
+       //rtlefuse->channel_plan = (u8) rtlefuse->eeprom_channelplan;
+
+       /*parse xtal*/
+       rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8821AE];
+       if ( rtlefuse->crystalcap == 0xFF )
+               rtlefuse->crystalcap = 0x20;
+
+       rtlefuse->eeprom_thermalmeter = *(u8 *) & hwinfo[EEPROM_THERMAL_METER];
+       if ((rtlefuse->eeprom_thermalmeter == 0xff) ||rtlefuse->autoload_failflag )
+       {
+               rtlefuse->b_apk_thermalmeterignore = true;
+               rtlefuse->eeprom_thermalmeter = 0x18;
+       }
+
+       rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+
+       if (rtlefuse->autoload_failflag == false) {
+               rtlefuse->antenna_div_cfg = (*(u8 *) & hwinfo[EEPROM_RF_BOARD_OPTION] & BIT(3))?true:false;
+               /*if (BT_1ant())
+                       rtlefuse->antenna_div_cfg = 0;*/
+
+               rtlefuse->antenna_div_type = CG_TRX_HW_ANTDIV;
+       } else {
+               rtlefuse->antenna_div_cfg = 0;
+               rtlefuse->antenna_div_type = 0;
+       }
+
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+               ("SWAS: bHwAntDiv = %x, TRxAntDivType = %x\n",
+                rtlefuse->antenna_div_cfg, rtlefuse->antenna_div_type));
+
+       pcipriv->ledctl.bled_opendrain = true;
+
+       if (rtlhal->oem_id == RT_CID_DEFAULT) {
+               switch (rtlefuse->eeprom_oemid) {
+               case RT_CID_DEFAULT:
+                       break;
+               case EEPROM_CID_TOSHIBA:
+                       rtlhal->oem_id = RT_CID_TOSHIBA;
+                       break;
+               case EEPROM_CID_CCX:
+                       rtlhal->oem_id = RT_CID_CCX;
+                       break;
+               case EEPROM_CID_QMI:
+                       rtlhal->oem_id = RT_CID_819x_QMI;
+                       break;
+               case EEPROM_CID_WHQL:
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+
+/*static void _rtl8821ae_hal_customized_behavior(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       pcipriv->ledctl.bled_opendrain = true;
+       switch (rtlhal->oem_id) {
+       case RT_CID_819x_HP:
+               pcipriv->ledctl.bled_opendrain = true;
+               break;
+       case RT_CID_819x_Lenovo:
+       case RT_CID_DEFAULT:
+       case RT_CID_TOSHIBA:
+       case RT_CID_CCX:
+       case RT_CID_819x_Acer:
+       case RT_CID_WHQL:
+       default:
+               break;
+       }
+       RT_TRACE(COMP_INIT, DBG_DMESG,
+                ("RT Customized ID: 0x%02X\n", rtlhal->oem_id));
+}*/
+
+void rtl8821ae_read_eeprom_info(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 tmp_u1b;
+
+       rtlhal->version = _rtl8821ae_read_chip_version(hw);
+
+       if (get_rf_type(rtlphy) == RF_1T1R)
+               rtlpriv->dm.brfpath_rxenable[0] = true;
+       else
+               rtlpriv->dm.brfpath_rxenable[0] =
+                   rtlpriv->dm.brfpath_rxenable[1] = true;
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
+                                               rtlhal->version));
+
+       tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
+       if (tmp_u1b & BIT(4)) {
+               RT_TRACE(COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+               rtlefuse->epromtype = EEPROM_93C46;
+       } else {
+               RT_TRACE(COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+               rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
+       }
+
+       if (tmp_u1b & BIT(5)) {
+               RT_TRACE(COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               rtlefuse->autoload_failflag = false;
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                       _rtl8812ae_read_adapter_info(hw, false);
+               else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE)
+                       _rtl8821ae_read_adapter_info(hw, false);
+       } else {
+                       RT_TRACE(COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+       }
+       /*hal_ReadRFType_8812A()*/
+       //_rtl8821ae_hal_customized_behavior(hw);
+}
+
+static void rtl8821ae_update_hal_rate_table(struct ieee80211_hw *hw,
+               struct ieee80211_sta *sta)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 ratr_value;
+       u8 ratr_index = 0;
+       u8 b_nmode = mac->ht_enable;
+       u8 mimo_ps = IEEE80211_SMPS_OFF;
+       u16 shortgi_rate;
+       u32 tmp_ratr_value;
+       u8 b_curtxbw_40mhz = mac->bw_40;
+       u8 b_curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+                               1 : 0;
+       u8 b_curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+                               1 : 0;
+       enum wireless_mode wirelessmode = mac->mode;
+
+       if (rtlhal->current_bandtype == BAND_ON_5G)
+               ratr_value = sta->supp_rates[1] << 4;
+       else
+               ratr_value = sta->supp_rates[0];
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               ratr_value = 0xfff;
+       ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+                       sta->ht_cap.mcs.rx_mask[0] << 12);
+       switch (wirelessmode) {
+       case WIRELESS_MODE_B:
+               if (ratr_value & 0x0000000c)
+                       ratr_value &= 0x0000000d;
+               else
+                       ratr_value &= 0x0000000f;
+               break;
+       case WIRELESS_MODE_G:
+               ratr_value &= 0x00000FF5;
+               break;
+       case WIRELESS_MODE_N_24G:
+       case WIRELESS_MODE_N_5G:
+               b_nmode = 1;
+               if (mimo_ps == IEEE80211_SMPS_STATIC) {
+                       ratr_value &= 0x0007F005;
+               } else {
+                       u32 ratr_mask;
+
+                       if (get_rf_type(rtlphy) == RF_1T2R ||
+                           get_rf_type(rtlphy) == RF_1T1R)
+                               ratr_mask = 0x000ff005;
+                       else
+                               ratr_mask = 0x0f0ff005;
+
+                       ratr_value &= ratr_mask;
+               }
+               break;
+       default:
+               if (rtlphy->rf_type == RF_1T2R)
+                       ratr_value &= 0x000ff0ff;
+               else
+                       ratr_value &= 0x0f0ff0ff;
+
+               break;
+       }
+
+       if ( (rtlpcipriv->btcoexist.bt_coexistence) &&
+            (rtlpcipriv->btcoexist.bt_coexist_type == BT_CSR_BC4) &&
+            (rtlpcipriv->btcoexist.bt_cur_state) &&
+            (rtlpcipriv->btcoexist.bt_ant_isolation) &&
+            ((rtlpcipriv->btcoexist.bt_service == BT_SCO)||
+            (rtlpcipriv->btcoexist.bt_service == BT_BUSY)) )
+               ratr_value &= 0x0fffcfc0;
+       else
+               ratr_value &= 0x0FFFFFFF;
+
+       if (b_nmode && ((b_curtxbw_40mhz &&
+                        b_curshortgi_40mhz) || (!b_curtxbw_40mhz &&
+                                                b_curshortgi_20mhz))) {
+
+               ratr_value |= 0x10000000;
+               tmp_ratr_value = (ratr_value >> 12);
+
+               for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
+                       if ((1 << shortgi_rate) & tmp_ratr_value)
+                               break;
+               }
+
+               shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
+                   (shortgi_rate << 4) | (shortgi_rate);
+       }
+
+       rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
+
+       RT_TRACE(COMP_RATR, DBG_DMESG,
+                ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
+}
+
+
+static u8 _rtl8821ae_mrate_idx_to_arfr_id(
+       struct ieee80211_hw *hw, u8 rate_index,
+       enum wireless_mode wirelessmode)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 ret = 0;
+       switch(rate_index){
+               case RATR_INX_WIRELESS_NGB:
+                       if(rtlphy->rf_type == RF_1T1R)
+                               ret = 1;
+                       else
+                               ret = 0;
+                       ;break;
+               case RATR_INX_WIRELESS_N:
+               case RATR_INX_WIRELESS_NG:
+                       if(rtlphy->rf_type == RF_1T1R)
+                               ret = 5;
+                       else
+                               ret = 4;
+                       ;break;
+               case RATR_INX_WIRELESS_NB:
+                       if(rtlphy->rf_type == RF_1T1R)
+                               ret = 3;
+                       else
+                               ret = 2;
+                       ;break;
+               case RATR_INX_WIRELESS_GB:
+                       ret = 6;
+                       break;
+               case RATR_INX_WIRELESS_G:
+                       ret = 7;
+                       break;
+               case RATR_INX_WIRELESS_B:
+                       ret = 8;
+                       break;
+               case RATR_INX_WIRELESS_MC:
+                       if ((wirelessmode == WIRELESS_MODE_B)
+                               || (wirelessmode == WIRELESS_MODE_G)
+                               || (wirelessmode == WIRELESS_MODE_N_24G)
+                               || (wirelessmode == WIRELESS_MODE_AC_24G))
+                               ret = 6;
+                       else
+                               ret = 7;
+               case RATR_INX_WIRELESS_AC_5N:
+                       if(rtlphy->rf_type == RF_1T1R)
+                               ret = 10;
+                       else
+                               ret = 9;
+                       break;
+               case RATR_INX_WIRELESS_AC_24N:
+                       if(rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
+                       {
+                               if(rtlphy->rf_type == RF_1T1R)
+                                       ret = 10;
+                               else
+                                       ret = 9;
+                       } else {
+                               if(rtlphy->rf_type == RF_1T1R)
+                                       ret = 11;
+                               else
+                                       ret = 12;
+                       }
+                       break;
+               default:
+                       ret = 0;break;
+       }
+       return ret;
+}
+
+static void rtl8821ae_update_hal_rate_mask(struct ieee80211_hw *hw,
+               struct ieee80211_sta *sta, u8 rssi_level)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_sta_info * sta_entry = NULL;
+       u32 ratr_bitmap;
+       u8 ratr_index;
+       u8 b_curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+                               ? 1 : 0;
+       u8 b_curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+                               1 : 0;
+       u8 b_curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+                               1 : 0;
+       enum wireless_mode wirelessmode = 0;
+       bool b_shortgi = false;
+       u8 rate_mask[7];
+       u8 macid = 0;
+       u8 mimo_ps = IEEE80211_SMPS_OFF;
+
+       sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+       wirelessmode = sta_entry->wireless_mode;
+       if (mac->opmode == NL80211_IFTYPE_STATION ||
+               mac->opmode == NL80211_IFTYPE_MESH_POINT)
+               b_curtxbw_40mhz = mac->bw_40;
+       else if (mac->opmode == NL80211_IFTYPE_AP ||
+               mac->opmode == NL80211_IFTYPE_ADHOC)
+               macid = sta->aid + 1;
+
+       ratr_bitmap = sta->supp_rates[0];
+
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               ratr_bitmap = 0xfff;
+
+       ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+                       sta->ht_cap.mcs.rx_mask[0] << 12);
+/*mac id owner*/
+       switch (wirelessmode) {
+       case WIRELESS_MODE_B:
+               ratr_index = RATR_INX_WIRELESS_B;
+               if (ratr_bitmap & 0x0000000c)
+                       ratr_bitmap &= 0x0000000d;
+               else
+                       ratr_bitmap &= 0x0000000f;
+               break;
+       case WIRELESS_MODE_G:
+               ratr_index = RATR_INX_WIRELESS_GB;
+
+               if (rssi_level == 1)
+                       ratr_bitmap &= 0x00000f00;
+               else if (rssi_level == 2)
+                       ratr_bitmap &= 0x00000ff0;
+               else
+                       ratr_bitmap &= 0x00000ff5;
+               break;
+       case WIRELESS_MODE_A:
+               ratr_index = RATR_INX_WIRELESS_G;
+               ratr_bitmap &= 0x00000ff0;
+               break;
+       case WIRELESS_MODE_N_24G:
+       case WIRELESS_MODE_N_5G:
+               if (wirelessmode == WIRELESS_MODE_N_24G)
+                       ratr_index = RATR_INX_WIRELESS_NGB;
+               else
+                       ratr_index = RATR_INX_WIRELESS_NG;
+
+               if (mimo_ps == IEEE80211_SMPS_STATIC  || mimo_ps == IEEE80211_SMPS_DYNAMIC) {
+                       if (rssi_level == 1)
+                               ratr_bitmap &= 0x00070000;
+                       else if (rssi_level == 2)
+                               ratr_bitmap &= 0x0007f000;
+                       else
+                               ratr_bitmap &= 0x0007f005;
+               } else {
+                       if ( rtlphy->rf_type == RF_1T1R) {
+                               if (b_curtxbw_40mhz) {
+                                       if (rssi_level == 1)
+                                               ratr_bitmap &= 0x000f0000;
+                                       else if (rssi_level == 2)
+                                               ratr_bitmap &= 0x000ff000;
+                                       else
+                                               ratr_bitmap &= 0x000ff015;
+                               } else {
+                                       if (rssi_level == 1)
+                                               ratr_bitmap &= 0x000f0000;
+                                       else if (rssi_level == 2)
+                                               ratr_bitmap &= 0x000ff000;
+                                       else
+                                               ratr_bitmap &= 0x000ff005;
+                               }
+                       } else {
+                               if (b_curtxbw_40mhz) {
+                                       if (rssi_level == 1)
+                                               ratr_bitmap &= 0x0fff0000;
+                                       else if (rssi_level == 2)
+                                               ratr_bitmap &= 0x0ffff000;
+                                       else
+                                               ratr_bitmap &= 0x0ffff015;
+                               } else {
+                                       if (rssi_level == 1)
+                                               ratr_bitmap &= 0x0fff0000;
+                                       else if (rssi_level == 2)
+                                               ratr_bitmap &= 0x0ffff000;
+                                       else
+                                               ratr_bitmap &= 0x0ffff005;
+                               }
+                       }
+               }
+               if ((b_curtxbw_40mhz && b_curshortgi_40mhz) ||
+                   (!b_curtxbw_40mhz && b_curshortgi_20mhz)) {
+
+                       if (macid == 0)
+                               b_shortgi = true;
+                       else if (macid == 1)
+                               b_shortgi = false;
+               }
+               break;
+
+       case WIRELESS_MODE_AC_24G:
+               ratr_index = RATR_INX_WIRELESS_AC_24N;
+               if(rssi_level == 1)
+                       ratr_bitmap &= 0xfc3f0000;
+               else if(rssi_level == 2)
+                       ratr_bitmap &= 0xfffff000;
+               else
+                       ratr_bitmap &= 0xffffffff;
+               break;
+
+       case WIRELESS_MODE_AC_5G:
+               ratr_index = RATR_INX_WIRELESS_AC_5N;
+
+               if (rtlphy->rf_type == RF_1T1R)
+               {
+                       if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                       {
+                               if(rssi_level == 1)                             /*add by Gary for ac-series*/
+                                       ratr_bitmap &= 0x003f8000;
+                               else if (rssi_level == 2)
+                                       ratr_bitmap &= 0x003ff000;
+                               else
+                                       ratr_bitmap &= 0x003ff010;
+                       }
+                       else
+                               ratr_bitmap &= 0x000ff010;
+               }
+               else
+               {
+                       if(rssi_level == 1)                             /* add by Gary for ac-series*/
+                               ratr_bitmap &= 0xfe3f8000;       /*VHT 2SS MCS3~9*/
+                       else if (rssi_level == 2)
+                               ratr_bitmap &= 0xfffff000;       /*VHT 2SS MCS0~9*/
+                       else
+                               ratr_bitmap &= 0xfffff010;       /*All*/
+               }
+               break;
+
+       default:
+               ratr_index = RATR_INX_WIRELESS_NGB;
+
+               if (rtlphy->rf_type == RF_1T2R)
+                       ratr_bitmap &= 0x000ff0ff;
+               else
+                       ratr_bitmap &= 0x0f0ff0ff;
+               break;
+
+       }
+
+       sta_entry->ratr_index = ratr_index;
+
+       RT_TRACE(COMP_RATR, DBG_DMESG,
+                ("ratr_bitmap :%x\n", ratr_bitmap));
+       *(u32 *) & rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
+                                      (ratr_index << 28));
+       rate_mask[0] = macid;
+       rate_mask[1] = _rtl8821ae_mrate_idx_to_arfr_id(hw, ratr_index, wirelessmode) | (b_shortgi ? 0x80 : 0x00);
+       rate_mask[2] = b_curtxbw_40mhz;
+       /* if (prox_priv->proxim_modeinfo->power_output > 0)
+               rate_mask[2] |= BIT(6); */
+
+       rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
+       rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >>8);
+       rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
+       rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
+
+       RT_TRACE(COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
+                                                "ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
+                                                ratr_index, ratr_bitmap,
+                                                rate_mask[0], rate_mask[1],
+                                                rate_mask[2], rate_mask[3],
+                                                rate_mask[4], rate_mask[5],
+                                                rate_mask[6]));
+       rtl8821ae_fill_h2c_cmd(hw, H2C_8821AE_RA_MASK, 7, rate_mask);
+       _rtl8821ae_set_bcn_ctrl_reg(hw, BIT(3), 0);
+}
+
+void rtl8821ae_update_hal_rate_tbl(struct ieee80211_hw *hw,
+               struct ieee80211_sta *sta, u8 rssi_level)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       if (rtlpriv->dm.b_useramask)
+               rtl8821ae_update_hal_rate_mask(hw, sta, rssi_level);
+       else
+               /*RT_TRACE(COMP_RATR,DBG_LOUD,("rtl8821ae_update_hal_rate_tbl(): Error! 8821ae FW RA Only"));*/
+               rtl8821ae_update_hal_rate_table(hw, sta);
+}
+
+void rtl8821ae_update_channel_access_setting(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       u16 sifs_timer;
+
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+                                     (u8 *) & mac->slot_time);
+       if (!mac->ht_enable)
+               sifs_timer = 0x0a0a;
+       else
+               sifs_timer = 0x0e0e;
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *) & sifs_timer);
+}
+
+bool rtl8821ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
+       u8 u1tmp = 0;
+       bool b_actuallyset = false;
+
+       if (rtlpriv->rtlhal.being_init_adapter)
+               return false;
+
+       if (ppsc->b_swrf_processing)
+               return false;
+
+       spin_lock(&rtlpriv->locks.rf_ps_lock);
+       if (ppsc->rfchange_inprogress) {
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
+               return false;
+       } else {
+               ppsc->rfchange_inprogress = true;
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
+       }
+
+       cur_rfstate = ppsc->rfpwr_state;
+
+       rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
+                                       rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
+
+       u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
+
+       if (rtlphy->polarity_ctl) {
+               e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
+       } else {
+               e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
+       }
+
+       if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) {
+               RT_TRACE(COMP_RF, DBG_DMESG,
+                        ("GPIOChangeRF  - HW Radio ON, RF ON\n"));
+
+               e_rfpowerstate_toset = ERFON;
+               ppsc->b_hwradiooff = false;
+               b_actuallyset = true;
+       } else if ((ppsc->b_hwradiooff == false)
+                  && (e_rfpowerstate_toset == ERFOFF)) {
+               RT_TRACE(COMP_RF, DBG_DMESG,
+                        ("GPIOChangeRF  - HW Radio OFF, RF OFF\n"));
+
+               e_rfpowerstate_toset = ERFOFF;
+               ppsc->b_hwradiooff = true;
+               b_actuallyset = true;
+       }
+
+       if (b_actuallyset) {
+               spin_lock(&rtlpriv->locks.rf_ps_lock);
+               ppsc->rfchange_inprogress = false;
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
+       } else {
+               if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
+                       RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+               spin_lock(&rtlpriv->locks.rf_ps_lock);
+               ppsc->rfchange_inprogress = false;
+               spin_unlock(&rtlpriv->locks.rf_ps_lock);
+       }
+
+       *valid = 1;
+       return !ppsc->b_hwradiooff;
+
+}
+
+void rtl8821ae_set_key(struct ieee80211_hw *hw, u32 key_index,
+                    u8 *p_macaddr, bool is_group, u8 enc_algo,
+                    bool is_wepkey, bool clear_all)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 *macaddr = p_macaddr;
+       u32 entry_id = 0;
+       bool is_pairwise = false;
+
+       static u8 cam_const_addr[4][6] = {
+               {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+               {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+               {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
+       };
+       static u8 cam_const_broad[] = {
+               0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+       };
+
+       if (clear_all) {
+               u8 idx = 0;
+               u8 cam_offset = 0;
+               u8 clear_number = 5;
+
+               RT_TRACE(COMP_SEC, DBG_DMESG, ("clear_all\n"));
+
+               for (idx = 0; idx < clear_number; idx++) {
+                       rtl_cam_mark_invalid(hw, cam_offset + idx);
+                       rtl_cam_empty_entry(hw, cam_offset + idx);
+
+                       if (idx < 5) {
+                               memset(rtlpriv->sec.key_buf[idx], 0,
+                                      MAX_KEY_LEN);
+                               rtlpriv->sec.key_len[idx] = 0;
+                       }
+               }
+
+       } else {
+               switch (enc_algo) {
+               case WEP40_ENCRYPTION:
+                       enc_algo = CAM_WEP40;
+                       break;
+               case WEP104_ENCRYPTION:
+                       enc_algo = CAM_WEP104;
+                       break;
+               case TKIP_ENCRYPTION:
+                       enc_algo = CAM_TKIP;
+                       break;
+               case AESCCMP_ENCRYPTION:
+                       enc_algo = CAM_AES;
+                       break;
+               default:
+                       RT_TRACE(COMP_ERR, DBG_EMERG, ("switch case "
+                                                               "not process \n"));
+                       enc_algo = CAM_TKIP;
+                       break;
+               }
+
+               if (is_wepkey || rtlpriv->sec.use_defaultkey) {
+                       macaddr = cam_const_addr[key_index];
+                       entry_id = key_index;
+               } else {
+                       if (is_group) {
+                               macaddr = cam_const_broad;
+                               entry_id = key_index;
+                       } else {
+                               if (mac->opmode == NL80211_IFTYPE_AP) {
+                                       entry_id = rtl_cam_get_free_entry(hw, p_macaddr);
+                                       if (entry_id >=  TOTAL_CAM_ENTRY) {
+                                               RT_TRACE(COMP_SEC, DBG_EMERG,
+                                                               ("Can not find free hw security cam entry\n"));
+                                               return;
+                                       }
+                               } else {
+                                       entry_id = CAM_PAIRWISE_KEY_POSITION;
+                               }
+
+                               key_index = PAIRWISE_KEYIDX;
+                               is_pairwise = true;
+                       }
+               }
+
+               if (rtlpriv->sec.key_len[key_index] == 0) {
+                       RT_TRACE(COMP_SEC, DBG_DMESG,
+                                ("delete one entry, entry_id is %d\n",entry_id));
+                       if (mac->opmode == NL80211_IFTYPE_AP)
+                               rtl_cam_del_entry(hw, p_macaddr);
+                       rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
+               } else {
+                       RT_TRACE(COMP_SEC, DBG_DMESG, ("add one entry\n"));
+                       if (is_pairwise) {
+                               RT_TRACE(COMP_SEC, DBG_DMESG, ("set Pairwiase key\n"));
+
+                               rtl_cam_add_one_entry(hw, macaddr, key_index,
+                                                     entry_id, enc_algo,
+                                                     CAM_CONFIG_NO_USEDK,
+                                                     rtlpriv->sec.key_buf[key_index]);
+                       } else {
+                               RT_TRACE(COMP_SEC, DBG_DMESG, ("set group key\n"));
+
+                               if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+                                       rtl_cam_add_one_entry(hw,
+                                                       rtlefuse->dev_addr,
+                                                       PAIRWISE_KEYIDX,
+                                                       CAM_PAIRWISE_KEY_POSITION,
+                                                       enc_algo,
+                                                       CAM_CONFIG_NO_USEDK,
+                                                       rtlpriv->sec.key_buf
+                                                       [entry_id]);
+                               }
+
+                               rtl_cam_add_one_entry(hw, macaddr, key_index,
+                                               entry_id, enc_algo,
+                                               CAM_CONFIG_NO_USEDK,
+                                               rtlpriv->sec.key_buf[entry_id]);
+                       }
+
+               }
+       }
+}
+
+
+void rtl8812ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+                                             bool auto_load_fail, u8 *hwinfo)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 value;
+
+       if (!auto_load_fail) {
+               value = *(u8 *) & hwinfo[EEPROM_RF_BOARD_OPTION];
+               if (((value & 0xe0) >> 5) == 0x1)
+                       rtlpriv->btcoexist.btc_info.btcoexist = 1;
+               else
+                       rtlpriv->btcoexist.btc_info.btcoexist = 0;
+               rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8812A;
+
+               value = hwinfo[EEPROM_RF_BT_SETTING];
+               rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
+       } else {
+               rtlpriv->btcoexist.btc_info.btcoexist = 0;
+               rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8812A;
+               rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
+       }
+       /*move BT_InitHalVars() to init_sw_vars*/
+}
+
+void rtl8821ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+                                             bool auto_load_fail, u8 *hwinfo)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 value;
+       u32 tmpu_32;
+
+       if (!auto_load_fail) {
+               tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
+               if(tmpu_32 & BIT(18))
+                       rtlpriv->btcoexist.btc_info.btcoexist = 1;
+               else
+                       rtlpriv->btcoexist.btc_info.btcoexist = 0;
+               rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8821A;
+
+               value = hwinfo[EEPROM_RF_BT_SETTING];
+               rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
+       } else {
+               rtlpriv->btcoexist.btc_info.btcoexist = 0;
+               rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8821A;
+               rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
+       }
+       /*move BT_InitHalVars() to init_sw_vars*/
+}
+
+void rtl8821ae_bt_reg_init(struct ieee80211_hw* hw)
+{
+       struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+       /* 0:Low, 1:High, 2:From Efuse. */
+       rtlpcipriv->btcoexist.b_reg_bt_iso = 2;
+       /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
+       rtlpcipriv->btcoexist.b_reg_bt_sco= 3;
+       /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
+       rtlpcipriv->btcoexist.b_reg_bt_sco= 0;
+}
+
+
+void rtl8821ae_bt_hw_init(struct ieee80211_hw* hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->cfg->ops->get_btc_status()){
+               rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
+       }
+}
+
+void rtl8821ae_suspend(struct ieee80211_hw *hw)
+{
+}
+
+void rtl8821ae_resume(struct ieee80211_hw *hw)
+{
+}
+
+/* Turn on AAP (RCR:bit 0) for promicuous mode. */
+void rtl8821ae_allow_all_destaddr(struct ieee80211_hw *hw,
+       bool allow_all_da, bool write_into_reg)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       if (allow_all_da) /* Set BIT0 */
+               rtlpci->receive_config |= RCR_AAP;
+       else /* Clear BIT0 */
+               rtlpci->receive_config &= ~RCR_AAP;
+
+       if(write_into_reg)
+               rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
+
+
+       RT_TRACE(COMP_TURBO | COMP_INIT, DBG_LOUD,
+               ("receive_config=0x%08X, write_into_reg=%d\n",
+               rtlpci->receive_config, write_into_reg ));
+}
+
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/hw.h b/drivers/staging/rtl8821ae/rtl8821ae/hw.h
new file mode 100644 (file)
index 0000000..4fb6bf0
--- /dev/null
@@ -0,0 +1,75 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_HW_H__
+#define __RTL8821AE_HW_H__
+
+void rtl8821ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
+void rtl8821ae_read_eeprom_info(struct ieee80211_hw *hw);
+
+void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw,
+                                                                                        u32 *p_inta, u32 *p_intb);
+int rtl8821ae_hw_init(struct ieee80211_hw *hw);
+void rtl8821ae_card_disable(struct ieee80211_hw *hw);
+void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw);
+void rtl8821ae_disable_interrupt(struct ieee80211_hw *hw);
+int rtl8821ae_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
+void rtl8821ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
+void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci);
+void rtl8821ae_set_beacon_related_registers(struct ieee80211_hw *hw);
+void rtl8821ae_set_beacon_interval(struct ieee80211_hw *hw);
+void rtl8821ae_update_interrupt_mask(struct ieee80211_hw *hw,
+                                                                                               u32 add_msr, u32 rm_msr);
+void rtl8821ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
+void rtl8821ae_update_hal_rate_tbl(struct ieee80211_hw *hw,
+                                                                                       struct ieee80211_sta *sta,
+                                                                                       u8 rssi_level);
+void rtl8821ae_update_channel_access_setting(struct ieee80211_hw *hw);
+bool rtl8821ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
+void rtl8821ae_enable_hw_security_config(struct ieee80211_hw *hw);
+void rtl8821ae_set_key(struct ieee80211_hw *hw, u32 key_index,
+                                               u8 *p_macaddr, bool is_group, u8 enc_algo,
+                                               bool is_wepkey, bool clear_all);
+
+void rtl8821ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+                                                                                                                       bool autoload_fail,
+                                                                                                                       u8* hwinfo);
+void rtl8812ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+                                                                                                                       bool autoload_fail,
+                                                                                                                       u8* hwinfo);
+void rtl8821ae_bt_reg_init(struct ieee80211_hw* hw);
+void rtl8821ae_bt_hw_init(struct ieee80211_hw* hw);
+void rtl8821ae_suspend(struct ieee80211_hw *hw);
+void rtl8821ae_resume(struct ieee80211_hw *hw);
+void rtl8821ae_allow_all_destaddr(struct ieee80211_hw *hw,
+                                                                                 bool allow_all_da,
+                                                                                 bool write_into_reg);
+void _rtl8821ae_stop_tx_beacon(struct ieee80211_hw *hw);
+void _rtl8821ae_resume_tx_beacon(struct ieee80211_hw *hw);
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/led.c b/drivers/staging/rtl8821ae/rtl8821ae/led.c
new file mode 100644 (file)
index 0000000..130a4f4
--- /dev/null
@@ -0,0 +1,239 @@
+/******************************************************************************
+ *
+ * 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 "../wifi.h"
+#include "../pci.h"
+#include "reg.h"
+
+static void _rtl8821ae_init_led(struct ieee80211_hw *hw,
+                                                                struct rtl_led *pled,
+                                                                enum rtl_led_pin ledpin)
+{
+       pled->hw = hw;
+       pled->ledpin = ledpin;
+       pled->b_ledon = false;
+}
+
+void rtl8821ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+       u8 ledcfg;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(COMP_LED, DBG_LOUD,
+                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+
+       switch (pled->ledpin) {
+       case LED_PIN_GPIO0:
+               break;
+       case LED_PIN_LED0:
+               ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
+               ledcfg &= ~BIT(6);
+               rtl_write_byte(rtlpriv,
+                              REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5));
+               break;
+       case LED_PIN_LED1:
+               ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
+               rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       }
+       pled->b_ledon = true;
+}
+
+void rtl8812ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+       u16     ledreg = REG_LEDCFG1;
+       u8      ledcfg = 0;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       switch (pled->ledpin) {
+               case LED_PIN_LED0:
+                       ledreg = REG_LEDCFG1;
+                       break;
+
+               case LED_PIN_LED1:
+                       ledreg = REG_LEDCFG2;
+                       break;
+
+               case LED_PIN_GPIO0:
+               default:
+                       break;
+       }
+
+       RT_TRACE(COMP_LED, DBG_LOUD, ("In SwLedOn, LedAddr:%X LEDPIN=%d \n", ledreg, pled->ledpin));
+
+       ledcfg =  rtl_read_byte(rtlpriv, ledreg);
+       ledcfg |= BIT(5); /*Set 0x4c[21]*/
+       ledcfg &= ~(BIT(7) | BIT(6) | BIT(3) |BIT(2) | BIT(1) |BIT(0));
+               /*Clear 0x4c[23:22] and 0x4c[19:16]*/
+       rtl_write_byte(rtlpriv, ledreg, ledcfg); /*SW control led0 on.*/
+       pled->b_ledon = true;
+}
+
+void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       u8 ledcfg;
+
+       RT_TRACE(COMP_LED, DBG_LOUD,
+                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+
+       ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
+
+       switch (pled->ledpin) {
+       case LED_PIN_GPIO0:
+               break;
+       case LED_PIN_LED0:
+               ledcfg &= 0xf0;
+               if (pcipriv->ledctl.bled_opendrain == true) {
+                       ledcfg &= 0x90; /* Set to software control. */
+                       rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
+                       ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
+                       ledcfg &= 0xFE;
+                       rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
+               }
+               else {
+                       ledcfg &= ~BIT(6);
+                       rtl_write_byte(rtlpriv, REG_LEDCFG2,
+                                       (ledcfg | BIT(3) | BIT(5)));
+               }
+               break;
+       case LED_PIN_LED1:
+               ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
+               ledcfg &= 0x10; /* Set to software control. */
+               rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3));
+
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       }
+       pled->b_ledon = false;
+}
+
+void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled){
+       u16 ledreg = REG_LEDCFG1;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+
+       switch(pled->ledpin)
+       {
+               case LED_PIN_LED0:
+                       ledreg = REG_LEDCFG1;
+                       break;
+
+               case LED_PIN_LED1:
+                       ledreg = REG_LEDCFG2;
+                       break;
+
+               case LED_PIN_GPIO0:
+               default:
+                       break;
+       }
+
+       RT_TRACE(COMP_LED,DBG_LOUD,("In SwLedOff,LedAddr:%X LEDPIN=%d\n", ledreg, pled->ledpin));
+
+       if(pcipriv->ledctl.bled_opendrain == true) /*Open-drain arrangement for controlling the LED*/
+       {
+               u8 ledcfg = rtl_read_byte(rtlpriv,  ledreg);
+
+               ledreg &= 0xd0; /* Set to software control.*/
+               rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3)));
+
+               /*Open-drain arrangement*/
+               ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
+               ledcfg &= 0xFE;/*Set GPIO[8] to input mode*/
+               rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
+       }
+       else
+       {
+               rtl_write_byte(rtlpriv, ledreg, 0x28);
+       }
+
+       pled->b_ledon = false;
+}
+
+void rtl8821ae_init_sw_leds(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       _rtl8821ae_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
+       _rtl8821ae_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
+}
+
+static void _rtl8821ae_sw_led_control(struct ieee80211_hw *hw,
+                                   enum led_ctl_mode ledaction)
+{
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       switch (ledaction) {
+       case LED_CTL_POWER_ON:
+       case LED_CTL_LINK:
+       case LED_CTL_NO_LINK:
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                       rtl8812ae_sw_led_on(hw, pLed0);
+               else
+                       rtl8821ae_sw_led_on(hw, pLed0);
+               break;
+       case LED_CTL_POWER_OFF:
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)\
+                       rtl8812ae_sw_led_off(hw, pLed0);
+               else
+                       rtl8821ae_sw_led_off(hw, pLed0);
+               break;
+       default:
+               break;
+       }
+}
+
+void rtl8821ae_led_control(struct ieee80211_hw *hw,
+                       enum led_ctl_mode ledaction)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
+           (ledaction == LED_CTL_TX ||
+            ledaction == LED_CTL_RX ||
+            ledaction == LED_CTL_SITE_SURVEY ||
+            ledaction == LED_CTL_LINK ||
+            ledaction == LED_CTL_NO_LINK ||
+            ledaction == LED_CTL_START_TO_LINK ||
+            ledaction == LED_CTL_POWER_ON)) {
+               return;
+       }
+       RT_TRACE(COMP_LED, DBG_LOUD, ("ledaction %d, \n",
+                               ledaction));
+       _rtl8821ae_sw_led_control(hw, ledaction);
+}
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/led.h b/drivers/staging/rtl8821ae/rtl8821ae/led.h
new file mode 100644 (file)
index 0000000..44be401
--- /dev/null
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_LED_H__
+#define __RTL8821AE_LED_H__
+
+void rtl8821ae_init_sw_leds(struct ieee80211_hw *hw);
+void rtl8821ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl8812ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl8821ae_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/phy.c b/drivers/staging/rtl8821ae/rtl8821ae/phy.c
new file mode 100644 (file)
index 0000000..09ffdc2
--- /dev/null
@@ -0,0 +1,5525 @@
+/******************************************************************************
+ *
+ * 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 "../wifi.h"
+#include "../pci.h"
+#include "../ps.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+#include "table.h"
+#include "trx.h"
+#include "../btcoexist/halbt_precomp.h"
+#include "hw.h"
+
+#define READ_NEXT_PAIR(array_table,v1, v2, i) do { i += 2; v1 = array_table[i]; v2 = array_table[i+1]; } while(0)
+
+static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
+                                     enum radio_path rfpath, u32 offset);
+static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
+                                       enum radio_path rfpath, u32 offset,
+                                       u32 data);
+static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask);
+static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw);
+static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
+static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
+static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+                                               u8 configtype);
+static bool _rtl8812ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+                                               u8 configtype);
+static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+                                                 u8 configtype);
+static bool _rtl8812ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+                                               u8 configtype);
+static void _rtl8821ae_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
+
+static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
+                                        enum wireless_mode wirelessmode,
+                                        u8 txpwridx);
+static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw);
+static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw);
+
+void rtl8812ae_fixspur(
+       struct ieee80211_hw *hw,
+       enum ht_channel_width band_width,
+       u8 channel
+)
+{
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       /*C cut Item12 ADC FIFO CLOCK*/
+       if(IS_VENDOR_8812A_C_CUT(rtlhal->version))
+       {
+               if(band_width == HT_CHANNEL_WIDTH_20_40 && channel == 11)
+                       rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x3)   ;
+                       /* 0x8AC[11:10] = 2'b11*/
+               else
+                       rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x2);
+                       /* 0x8AC[11:10] = 2'b10*/
+
+
+               /* <20120914, Kordan> A workarould to resolve
+               2480Mhz spur by setting ADC clock as 160M. (Asked by Binson)*/
+               if (band_width == HT_CHANNEL_WIDTH_20 &&
+                       (channel == 13 || channel == 14)) {
+                       rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
+                       /*0x8AC[9:8] = 2'b11*/
+                       rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
+                       /* 0x8C4[30] = 1*/
+               } else if (band_width == HT_CHANNEL_WIDTH_20_40 &&
+                       channel == 11) {
+                       rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
+                       /*0x8C4[30] = 1*/
+               } else if (band_width != HT_CHANNEL_WIDTH_80) {
+                       rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
+                       /*0x8AC[9:8] = 2'b10*/
+                       rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
+                       /*0x8C4[30] = 0*/
+               }
+       }
+       else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+       {
+               /* <20120914, Kordan> A workarould to resolve
+               2480Mhz spur by setting ADC clock as 160M. (Asked by Binson)*/
+               if (band_width == HT_CHANNEL_WIDTH_20 &&
+                       (channel == 13 || channel == 14))
+                       rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
+                       /*0x8AC[9:8] = 11*/
+               else if (channel  <= 14) /*2.4G only*/
+                       rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
+                       /*0x8AC[9:8] = 10*/
+       }
+
+}
+
+u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 returnvalue, originalvalue, bitshift;
+
+       RT_TRACE(COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+                                              "bitmask(%#x)\n", regaddr,
+                                              bitmask));
+       originalvalue = rtl_read_dword(rtlpriv, regaddr);
+       bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
+       returnvalue = (originalvalue & bitmask) >> bitshift;
+
+       RT_TRACE(COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
+                                              "Addr[0x%x]=0x%x\n", bitmask,
+                                              regaddr, originalvalue));
+
+       return returnvalue;
+
+}
+
+void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw,
+                          u32 regaddr, u32 bitmask, u32 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 originalvalue, bitshift;
+
+       RT_TRACE(COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+                                              " data(%#x)\n", regaddr, bitmask,
+                                              data));
+
+       if (bitmask != MASKDWORD) {
+               originalvalue = rtl_read_dword(rtlpriv, regaddr);
+               bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
+               data = ((originalvalue & (~bitmask)) | ((data << bitshift) & bitmask));
+       }
+
+       rtl_write_dword(rtlpriv, regaddr, data);
+
+       RT_TRACE(COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+                                              " data(%#x)\n", regaddr, bitmask,
+                                              data));
+
+}
+
+u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw,
+                           enum radio_path rfpath, u32 regaddr, u32 bitmask)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 original_value, readback_value, bitshift;
+       unsigned long flags;
+
+       RT_TRACE(COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+                                              "rfpath(%#x), bitmask(%#x)\n",
+                                              regaddr, rfpath, bitmask));
+
+       spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+
+       original_value = _rtl8821ae_phy_rf_serial_read(hw,rfpath, regaddr);
+       bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
+       readback_value = (original_value & bitmask) >> bitshift;
+
+       spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+       RT_TRACE(COMP_RF, DBG_TRACE,
+                ("regaddr(%#x), rfpath(%#x), "
+                 "bitmask(%#x), original_value(%#x)\n",
+                 regaddr, rfpath, bitmask, original_value));
+
+       return readback_value;
+}
+
+void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw,
+                          enum radio_path rfpath,
+                          u32 regaddr, u32 bitmask, u32 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 original_value, bitshift;
+       unsigned long flags;
+
+       RT_TRACE(COMP_RF, DBG_TRACE,
+                ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                 regaddr, bitmask, data, rfpath));
+
+       spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+       if (bitmask != RFREG_OFFSET_MASK) {
+                       original_value = _rtl8821ae_phy_rf_serial_read(hw,
+                                                                   rfpath,
+                                                                   regaddr);
+                       bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
+                       data =
+                           ((original_value & (~bitmask)) |
+                            (data << bitshift));
+               }
+
+       _rtl8821ae_phy_rf_serial_write(hw, rfpath, regaddr, data);
+
+
+       spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+       RT_TRACE(COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+                                              "bitmask(%#x), data(%#x), rfpath(%#x)\n",
+                                              regaddr, bitmask, data, rfpath));
+
+}
+
+static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
+                                     enum radio_path rfpath, u32 offset)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool b_is_pi_mode =false;
+       u32 retvalue = 0;
+
+       /* 2009/06/17 MH We can not execute IO for power save or other accident mode.*/
+       if (RT_CANNOT_IO(hw)) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("return all one\n"));
+               return 0xFFFFFFFF;
+       }
+
+       /* <20120809, Kordan> CCA OFF(when entering), asked by James to avoid reading the wrong value.
+           <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/
+       if (offset != 0x0 &&
+               !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE)
+               || (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
+               rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1);
+
+       offset &= 0xff;
+
+       if (rfpath == RF90_PATH_A)
+               b_is_pi_mode = (bool) rtl_get_bbreg(hw, 0xC00, 0x4);
+       else if (rfpath == RF90_PATH_B)
+               b_is_pi_mode = (bool) rtl_get_bbreg(hw, 0xE00, 0x4);
+
+       rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset);
+
+       if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE)
+               || (IS_VENDOR_8812A_C_CUT(rtlhal->version)))
+               udelay(20);
+
+       if (b_is_pi_mode)
+       {
+               if (rfpath == RF90_PATH_A) {
+                       retvalue = rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA);
+               }
+               else if (rfpath == RF90_PATH_B){
+                       retvalue = rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA);
+               }
+       }
+       else
+       {
+               if (rfpath == RF90_PATH_A) {
+                       retvalue = rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA);
+               }
+               else if (rfpath == RF90_PATH_B){
+                       retvalue = rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA);
+               }
+       }
+
+       /*<20120809, Kordan> CCA ON(when exiting), asked by James to avoid reading the wrong value.
+           <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/
+       if (offset != 0x0 &&  ! ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE)
+               || (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
+               rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0);
+       return retvalue;
+}
+
+#if 0
+static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
+                                     enum radio_path rfpath, u32 offset)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+       u32 newoffset;
+       u32 tmplong, tmplong2;
+       u8 rfpi_enable = 0;
+       u32 retvalue;
+
+       offset &= 0xff;
+       newoffset = offset;
+       if (RT_CANNOT_IO(hw)) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("return all one\n"));
+               return 0xFFFFFFFF;
+       }
+       tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
+       if (rfpath == RF90_PATH_A)
+               tmplong2 = tmplong;
+       else
+               tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
+       tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
+           (newoffset << 23) | BLSSIREADEDGE;
+       rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
+                     tmplong & (~BLSSIREADEDGE));
+       mdelay(1);
+       rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
+       mdelay(1);
+       /*rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
+                     tmplong | BLSSIREADEDGE);*/
+       mdelay(1);
+       if (rfpath == RF90_PATH_A)
+               rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
+                                                BIT(8));
+       else if (rfpath == RF90_PATH_B)
+               rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
+                                                BIT(8));
+       if (rfpi_enable)
+               retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
+                                        BLSSIREADBACKDATA);
+       else
+               retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
+                                        BLSSIREADBACKDATA);
+       RT_TRACE(COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
+                                              rfpath, pphyreg->rflssi_readback,
+                                              retvalue));
+       return retvalue;
+}
+#endif
+
+static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
+                                       enum radio_path rfpath, u32 offset,
+                                       u32 data)
+{
+       u32 data_and_addr;
+       u32 newoffset;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+
+       if (RT_CANNOT_IO(hw)) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("stop\n"));
+               return;
+       }
+       offset &= 0xff;
+       newoffset = offset;
+       data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
+       rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
+       RT_TRACE(COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
+                                              rfpath, pphyreg->rf3wire_offset,
+                                              data_and_addr));
+}
+
+static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask)
+{
+       u32 i;
+
+       for (i = 0; i <= 31; i++) {
+               if (((bitmask >> i) & 0x1) == 1)
+                       break;
+       }
+       return i;
+}
+
+bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw)
+{
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool rtstatus = 0;
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+               rtstatus = _rtl8812ae_phy_config_mac_with_headerfile(hw);
+       else
+               rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw);
+
+       return rtstatus;
+}
+
+bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw)
+{
+       bool rtstatus = true;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 regval;
+       u8 crystal_cap;
+       //u32 tmp;
+
+       _rtl8821ae_phy_init_bb_rf_register_definition(hw);
+
+       regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
+       regval |= regval | FEN_PCIEA;
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
+                               regval | FEN_BB_GLB_RSTN | FEN_BBRSTB);
+
+       rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7);/*RF_EN | RF_RSTB | RF_SDMRSTB*/
+       rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7);/*RF_EN | RF_RSTB | RF_SDMRSTB*/
+
+       rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw);
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+       {
+               crystal_cap = rtlefuse->crystalcap & 0x3F;
+               rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
+       }else{
+               crystal_cap = rtlefuse->crystalcap & 0x3F;
+               rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, (crystal_cap | (crystal_cap << 6)));
+       }
+       rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);
+
+       return rtstatus;
+}
+
+bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw)
+{
+       return rtl8821ae_phy_rf6052_config(hw);
+}
+
+
+u32 phy_get_tx_bb_swing_8812A(
+       struct ieee80211_hw *hw,
+       u8      band,
+       u8      rf_path
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_dm *rtldm = rtl_dm(rtlpriv);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+       char bb_swing_2g = (char) (-1 * 0xFF);
+       char bb_swing_5g = (char) (-1 * 0xFF);
+       u32  out = 0x200;
+       const char auto_temp = -1;
+
+       RT_TRACE(COMP_SCAN, DBG_LOUD,
+               ("===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d\n",
+               (int)bb_swing_2g, (int)bb_swing_5g));
+
+    if ( rtlefuse->autoload_failflag) {
+               if ( band == BAND_ON_2_4G ) {
+                       rtldm->bb_swing_diff_2g = bb_swing_2g;
+                       if      (bb_swing_2g == 0)  out = 0x200; //  0 dB
+                       else if (bb_swing_2g == -3) out = 0x16A; // -3 dB
+                       else if (bb_swing_2g == -6) out = 0x101; // -6 dB
+                       else if (bb_swing_2g == -9) out = 0x0B6; // -9 dB
+                       else {
+                               rtldm->bb_swing_diff_2g = 0;
+                               out = 0x200;
+                       }
+
+               } else if ( band == BAND_ON_5G ) {
+                       rtldm->bb_swing_diff_5g = bb_swing_5g;
+                       if      (bb_swing_5g == 0)  out = 0x200; //  0 dB
+                       else if (bb_swing_5g == -3) out = 0x16A; // -3 dB
+                       else if (bb_swing_5g == -6) out = 0x101; // -6 dB
+                       else if (bb_swing_5g == -9) out = 0x0B6; // -9 dB
+                       else {
+                               if ( rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+                                       rtldm->bb_swing_diff_5g = -3;
+                                       out = 0x16A;
+                               } else  {
+                                       rtldm->bb_swing_diff_5g = 0;
+                                       out = 0x200;
+                               }
+                       }
+               } else  {
+                               rtldm->bb_swing_diff_2g = -3;
+                               rtldm->bb_swing_diff_5g = -3;
+                               out = 0x16A; // -3 dB
+               }
+       }
+       else
+       {
+           u32 swing = 0, swing_a = 0, swing_b = 0;
+
+           if (band == BAND_ON_2_4G)
+           {
+                       if (0xFF == auto_temp)
+                       {
+                               efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
+                               swing = (swing == 0xFF) ? 0x00 : swing;
+                       }
+                       else if (bb_swing_2g ==  0) swing = 0x00; //  0 dB
+                       else if (bb_swing_2g == -3) swing = 0x05; // -3 dB
+                       else if (bb_swing_2g == -6) swing = 0x0A; // -6 dB
+                       else if (bb_swing_2g == -9) swing = 0xFF; // -9 dB
+                       else swing = 0x00;
+               }
+               else
+               {
+                       if (0xFF == auto_temp)
+                       {
+                               efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
+                               swing = (swing == 0xFF) ? 0x00 : swing;
+                       }
+                       else if (bb_swing_5g ==  0) swing = 0x00; //  0 dB
+                       else if (bb_swing_5g == -3) swing = 0x05; // -3 dB
+                       else if (bb_swing_5g == -6) swing = 0x0A; // -6 dB
+                       else if (bb_swing_5g == -9) swing = 0xFF; // -9 dB
+                       else swing = 0x00;
+               }
+
+               swing_a = (swing & 0x3) >> 0; // 0xC6/C7[1:0]
+               swing_b = (swing & 0xC) >> 2; // 0xC6/C7[3:2]
+               RT_TRACE(COMP_SCAN, DBG_LOUD,
+               ("===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
+               swing_a, swing_b));
+
+               //3 Path-A
+               if (swing_a == 0x0) {
+                       if (band == BAND_ON_2_4G)
+                               rtldm->bb_swing_diff_2g = 0;
+                       else
+                               rtldm->bb_swing_diff_5g = 0;
+                       out = 0x200; // 0 dB
+               } else if (swing_a == 0x1) {
+                       if (band == BAND_ON_2_4G)
+                               rtldm->bb_swing_diff_2g = -3;
+                       else
+                               rtldm->bb_swing_diff_5g = -3;
+                       out = 0x16A; // -3 dB
+               } else if (swing_a == 0x2) {
+                       if (band == BAND_ON_2_4G)
+                               rtldm->bb_swing_diff_2g = -6;
+                       else
+                               rtldm->bb_swing_diff_5g = -6;
+                       out = 0x101; // -6 dB
+               } else if (swing_a == 0x3) {
+                       if (band == BAND_ON_2_4G)
+                               rtldm->bb_swing_diff_2g = -9;
+                       else
+                               rtldm->bb_swing_diff_5g = -9;
+                       out = 0x0B6; // -9 dB
+               }
+
+                       //3 Path-B
+               if (swing_b == 0x0) {
+                       if (band == BAND_ON_2_4G)
+                               rtldm->bb_swing_diff_2g = 0;
+                       else
+                               rtldm->bb_swing_diff_5g = 0;
+                       out = 0x200; // 0 dB
+               } else if (swing_b == 0x1) {
+                       if (band == BAND_ON_2_4G)
+                               rtldm->bb_swing_diff_2g = -3;
+                       else
+                               rtldm->bb_swing_diff_5g = -3;
+                       out = 0x16A; // -3 dB
+               } else if (swing_b == 0x2) {
+                       if (band == BAND_ON_2_4G)
+                               rtldm->bb_swing_diff_2g = -6;
+                       else
+                               rtldm->bb_swing_diff_5g = -6;
+                       out = 0x101; // -6 dB
+               } else if (swing_b == 0x3) {
+                       if (band == BAND_ON_2_4G)
+                               rtldm->bb_swing_diff_2g = -9;
+                       else
+                               rtldm->bb_swing_diff_5g = -9;
+                       out = 0x0B6; // -9 dB
+               }
+       }
+
+       RT_TRACE(COMP_SCAN, DBG_LOUD,
+               ("<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out));
+        return out;
+}
+void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_dm *rtldm = rtl_dm(rtlpriv);
+       u8 current_band = rtlhal->current_bandtype;
+       u32 txpath, rxpath;
+       //u8 i, value8;
+       char bb_diff_between_band;
+
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("\n"));
+       txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
+       rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
+       rtlhal->current_bandtype = (enum band_type) band;
+       /* reconfig BB/RF according to wireless mode */
+       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+               /* BB & RF Config */
+               RT_TRACE(COMP_CMD, DBG_DMESG, ("2.4G\n"));
+               rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
+
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+                       /* 0xCB0[15:12] = 0x7 (LNA_On)*/
+                       rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
+                       /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
+                       rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
+               }
+
+               if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
+                       rtl_set_bbreg(hw, 0x830, 0xE, 0x4);     /*0x830[3:1] = 0x4*/
+                       rtl_set_bbreg(hw, 0x834, 0x3, 0x1);     /*0x834[1:0] = 0x1*/
+               }
+
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE)
+                       rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0); // 0xC1C[11:8] = 0
+               else
+                       rtl_set_bbreg(hw, 0x82c, 0x3, 0);       // 0x82C[1:0] = 2b'00
+
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
+                       rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777);
+                       rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
+                       rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x000);
+                       rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x000);
+               }
+
+               rtl_set_bbreg(hw, RTXPATH, 0xf0, txpath);
+               rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, rxpath);
+
+               rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
+       } else {/* 5G band */
+               u16 count, reg_41a;
+               RT_TRACE(COMP_CMD, DBG_DMESG, ("5G\n"));
+
+               if(rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+                       /*0xCB0[15:12] = 0x5 (LNA_On)*/
+                       rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
+                       /*0xCB0[7:4] = 0x4 (PAPE_A)*/
+                       rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
+               }
+               /*CCK_CHECK_en*/
+               rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
+
+               count = 0;
+               reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
+               RT_TRACE(COMP_SCAN, DBG_LOUD, ("Reg41A value %d", reg_41a));
+               reg_41a &= 0x30;
+               while ((reg_41a!= 0x30) && (count < 50)) {
+                       udelay(50);
+                       RT_TRACE(COMP_SCAN, DBG_LOUD, ("Delay 50us \n"));
+
+                       reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
+                       reg_41a &= 0x30;
+                       count++;
+                       RT_TRACE(COMP_SCAN, DBG_LOUD, ("Reg41A value %d", reg_41a));
+               }
+               if (count != 0)
+                       RT_TRACE(COMP_MLME, DBG_LOUD,
+                       ("PHY_SwitchWirelessBand8812(): Switch to 5G Band. "
+                       "Count = %d reg41A=0x%x\n", count, reg_41a));
+
+               // 2012/02/01, Sinda add registry to switch workaround without long-run verification for scan issue.
+               rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
+
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
+                       rtl_set_bbreg(hw, 0x830, 0xE, 0x3);     /*0x830[3:1] = 0x3*/
+                       rtl_set_bbreg(hw, 0x834, 0x3, 0x2);     /*0x834[1:0] = 0x2*/
+               }
+
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+                       /* AGC table select */
+                       rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1); /* 0xC1C[11:8] = 1*/
+               } else
+                       rtl_set_bbreg(hw, 0x82c, 0x3, 1);       // 0x82C[1:0] = 2'b00
+
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
+                       rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337777);
+                       rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
+                       rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x010);
+                       rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x010);
+               }
+
+               rtl_set_bbreg(hw, RTXPATH, 0xf0, txpath);
+               rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, rxpath);
+
+               RT_TRACE(COMP_SCAN, DBG_LOUD,
+                       ("==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
+                       rtlpriv->dm.ofdm_index[RF90_PATH_A]));
+       }
+
+       if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
+                       (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
+               rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
+                                                phy_get_tx_bb_swing_8812A(hw, band, RF90_PATH_A)); // 0xC1C[31:21]
+               rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
+                                                phy_get_tx_bb_swing_8812A(hw, band, RF90_PATH_B)); // 0xE1C[31:21]
+
+               /* <20121005, Kordan> When TxPowerTrack is ON, we should take care of the change of BB swing.
+                   That is, reset all info to trigger Tx power tracking.*/
+               if (band != current_band) {
+                       bb_diff_between_band = (rtldm->bb_swing_diff_2g - rtldm->bb_swing_diff_5g);
+                       bb_diff_between_band = (band == BAND_ON_2_4G) ? bb_diff_between_band : (-1 * bb_diff_between_band);
+                       rtldm->default_ofdm_index += bb_diff_between_band * 2;
+               }
+               rtl8821ae_dm_clear_txpower_tracking_state(hw);
+       }
+
+       RT_TRACE(COMP_SCAN, DBG_TRACE,
+               ("<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n"));
+       return;
+}
+
+static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
+       const u32  Condition
+       )
+{
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u32 _board = rtlefuse->board_type; /*need efuse define*/
+       u32 _interface = rtlhal->interface;
+       u32 _platform = 0x08;/*SupportPlatform */
+       u32 cond = Condition;
+
+       if ( Condition == 0xCDCDCDCD )
+               return true;
+
+       cond = Condition & 0xFF;
+       if ( (_board != cond) == 0 && cond != 0xFF)
+               return false;
+
+       cond = Condition & 0xFF00;
+       cond = cond >> 8;
+       if ( (_interface & cond) == 0 && cond != 0x07)
+               return false;
+
+       cond = Condition & 0xFF0000;
+       cond = cond >> 16;
+       if ( (_platform & cond) == 0 && cond != 0x0F)
+               return false;
+       return true;
+}
+
+static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
+       u32 addr,
+       u32 data,
+       enum radio_path rfpath,
+       u32 regaddr
+       )
+{
+       if ( addr == 0xfe || addr == 0xffe) {
+               mdelay(50);
+       } else {
+               rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
+               udelay(1);
+       }
+}
+
+static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
+       u32 addr, u32 data)
+{
+       u32 content = 0x1000; /*RF Content: radio_a_txt*/
+       u32 maskforphyset = (u32)(content & 0xE000);
+
+       _rtl8821ae_config_rf_reg(hw, addr, data, RF90_PATH_A, addr | maskforphyset);
+
+}
+
+static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
+       u32 addr, u32 data)
+{
+       u32 content = 0x1001; /*RF Content: radio_b_txt*/
+       u32 maskforphyset = (u32)(content & 0xE000);
+
+       _rtl8821ae_config_rf_reg(hw, addr, data, RF90_PATH_B, addr | maskforphyset);
+
+}
+
+static void _rtl8812ae_config_bb_reg(struct ieee80211_hw *hw,
+       u32 addr, u32 data)
+{
+       if ( addr == 0xfe) {
+               mdelay(50);
+       } else if ( addr == 0xfd)
+               mdelay(5);
+       else if ( addr == 0xfc)
+               mdelay(1);
+       else if ( addr == 0xfb)
+               udelay(50);
+       else if ( addr == 0xfa)
+               udelay(5);
+       else if ( addr == 0xf9)
+               udelay(1);
+       else {
+               rtl_set_bbreg(hw, addr, MASKDWORD,data);
+       }
+       udelay(1);
+}
+
+static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
+       u32 addr, u32 data)
+{
+       if ( addr == 0xfe) {
+               mdelay(50);
+       } else if ( addr == 0xfd)
+               mdelay(5);
+       else if ( addr == 0xfc)
+               mdelay(1);
+       else if ( addr == 0xfb)
+               udelay(50);
+       else if ( addr == 0xfa)
+               udelay(5);
+       else if ( addr == 0xf9)
+               udelay(1);
+
+       rtl_set_bbreg(hw, addr, MASKDWORD,data);
+       udelay(1);
+}
+
+static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       u8 band, rfpath, txnum, rate_section;
+
+       for ( band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band )
+               for ( rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath )
+                       for ( txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum )
+                               for ( rate_section = 0; rate_section < TX_PWR_BY_RATE_NUM_SECTION; ++rate_section )
+                                       rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = 0;
+}
+
+void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
+                                                                                                                  u8 band, u8 path,
+                                                                                                                  u8 rate_section,
+                                                                                                                  u8 txnum, u8 value)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       if (path > RF90_PATH_D) {
+               RT_TRACE(COMP_INIT, DBG_LOUD,
+                       ("Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path));
+               return;
+       }
+
+       if (band == BAND_ON_2_4G) {
+               switch (rate_section) {
+               case CCK:
+                       rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
+                       break;
+               case OFDM:
+                       rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
+                       break;
+               case HT_MCS0_MCS7:
+                       rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
+                       break;
+               case HT_MCS8_MCS15:
+                       rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
+                       break;
+               case VHT_1SSMCS0_1SSMCS9:
+                       rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
+                       break;
+               case VHT_2SSMCS0_2SSMCS9:
+                       rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
+                       break;
+               default:
+                       RT_TRACE(COMP_INIT, DBG_LOUD, ( "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
+                                        rate_section, path, txnum ) );
+                       break;
+               };
+       } else if (band == BAND_ON_5G) {
+               switch (rate_section) {
+               case OFDM:
+                       rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
+                       break;
+               case HT_MCS0_MCS7:
+                       rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
+                       break;
+               case HT_MCS8_MCS15:
+                       rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
+                       break;
+               case VHT_1SSMCS0_1SSMCS9:
+                       rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
+                       break;
+               case VHT_2SSMCS0_2SSMCS9:
+                       rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
+                       break;
+               default:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Invalid RateSection %d in Band 5G, Rf Path %d, "
+                               "%dTx in PHY_SetTxPowerByRateBase()\n",
+                               rate_section, path, txnum));
+                       break;
+               };
+       } else {
+               RT_TRACE(COMP_INIT, DBG_LOUD,
+                       ("Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band));
+       }
+
+}
+
+u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
+                                                                                                                u8 band, u8 path,
+                                                                                                                u8 txnum, u8 rate_section)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 value = 0;
+
+       if (path > RF90_PATH_D) {
+               RT_TRACE(COMP_INIT, DBG_LOUD,
+                       ("Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n", path));
+               return 0;
+       }
+
+       if (band == BAND_ON_2_4G) {
+               switch (rate_section) {
+               case CCK:
+                       value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
+                       break;
+               case OFDM:
+                       value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
+                       break;
+               case HT_MCS0_MCS7:
+                       value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
+                       break;
+               case HT_MCS8_MCS15:
+                       value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
+                       break;
+               case VHT_1SSMCS0_1SSMCS9:
+                       value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
+                       break;
+               case VHT_2SSMCS0_2SSMCS9:
+                       value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
+                       break;
+               default:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Invalid RateSection %d in Band 2.4G, Rf Path %d,"
+                               " %dTx in PHY_GetTxPowerByRateBase()\n",
+                               rate_section, path, txnum));
+                       break;
+               };
+       } else if (band == BAND_ON_5G) {
+               switch (rate_section) {
+               case OFDM:
+                       value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
+                       break;
+               case HT_MCS0_MCS7:
+                       value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
+                       break;
+               case HT_MCS8_MCS15:
+                       value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
+                       break;
+               case VHT_1SSMCS0_1SSMCS9:
+                       value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
+                       break;
+               case VHT_2SSMCS0_2SSMCS9:
+                       value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
+                       break;
+               default:
+                       RT_TRACE(COMP_INIT, DBG_LOUD,
+                               ("Invalid RateSection %d in Band 5G, Rf Path %d,"
+                               " %dTx in PHY_GetTxPowerByRateBase()\n",
+                               rate_section, path, txnum));
+                       break;
+               };
+       } else {
+               RT_TRACE(COMP_INIT, DBG_LOUD,
+                       ("Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band));
+       }
+
+       return value;
+
+}
+void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u16 rawValue = 0;
+       u8 base = 0, path = 0;
+
+       for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base );
+
+               rawValue = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
+               base = (rawValue >> 4) * 10 + (rawValue & 0xF);
+               _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base );
+       }
+}
+
+void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
+                                                                                                                               u8 end, u8 base_val)
+{
+       char i = 0;
+       u8 temp_value = 0;
+       u32 temp_data = 0;
+
+       for (i = 3; i >= 0; --i)
+       {
+               if (i >= start && i <= end) {
+                       // Get the exact value
+                       temp_value = (u8) (*data >> (i * 8)) & 0xF;
+                       temp_value += ((u8) ((*data >> (i * 8 + 4)) & 0xF)) * 10;
+
+                       // Change the value to a relative value
+                       temp_value = (temp_value > base_val) ? temp_value - base_val : base_val - temp_value;
+               } else {
+                       temp_value = (u8) (*data >> (i * 8)) & 0xFF;
+               }
+               temp_data <<= 8;
+               temp_data |= temp_value;
+       }
+       *data = temp_data;
+}
+
+void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 base = 0, rfPath = 0;
+
+       for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) {
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 2.4G CCK 1TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0] ),
+                       0, 3, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 2.4G OFDM 1TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2] ),
+                       0, 3, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7 );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 2.4G HTMCS0-7 1TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4] ),
+                       0, 3, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15 );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 2.4G HTMCS8-15 2TX: %d\n", base ) );
+
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5] ),
+                       0, 3, base );
+
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6] ),
+                       0, 3, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9 );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 2.4G VHT1SSMCS0-9 1TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9] ),
+                       0, 1, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9 );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 2.4G VHT2SSMCS0-9 2TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9] ),
+                       2, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11] ),
+                       0, 3, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 5G OFDM 1TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2] ),
+                       0, 3, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7 );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 5G HTMCS0-7 1TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4] ),
+                       0, 3, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15 );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 5G HTMCS8-15 2TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6] ),
+                       0, 3, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9 );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 5G VHT1SSMCS0-9 1TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9] ),
+                       0, 1, base );
+
+               base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9 );
+               RT_DISP( FPHY, PHY_TXPWR, ( "base of 5G VHT2SSMCS0-9 2TX: %d\n", base ) );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9] ),
+                       2, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10] ),
+                       0, 3, base );
+               _phy_convert_txpower_dbm_to_relative_value(
+                       &(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11] ),
+                       0, 3, base );
+       }
+
+       RT_TRACE(COMP_POWER, DBG_TRACE,
+               ("<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n"));
+
+}
+
+void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
+{
+       _rtl8821ae_phy_store_txpower_by_rate_base(hw);
+       _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
+}
+
+static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       bool rtstatus;
+
+       /*TX POWER LIMIT
+           PHY_InitTxPowerLimit
+           PHY_ConfigRFWithCustomPowerLimitTableParaFile*/
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+               rtstatus = _rtl8812ae_phy_config_bb_with_headerfile(hw,
+                                                               BASEBAND_CONFIG_PHY_REG);
+       else{
+               rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
+                                                               BASEBAND_CONFIG_PHY_REG);
+       }
+       if (rtstatus != true) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
+               return false;
+       }
+       _rtl8821ae_phy_init_tx_power_by_rate(hw);
+       if (rtlefuse->autoload_failflag == false) {
+               //rtlphy->pwrgroup_cnt = 0;
+               if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                       rtstatus = _rtl8812ae_phy_config_bb_with_pgheaderfile(hw,
+                                                                  BASEBAND_CONFIG_PHY_REG);
+               else{
+                       rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
+                                                                  BASEBAND_CONFIG_PHY_REG);
+               }
+       }
+       if (rtstatus != true) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
+               return false;
+       }
+
+       _rtl8821ae_phy_txpower_by_rate_configuration(hw);
+
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+               rtstatus = _rtl8812ae_phy_config_bb_with_headerfile(hw,
+                                                        BASEBAND_CONFIG_AGC_TAB);
+       else
+               rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
+                                                        BASEBAND_CONFIG_AGC_TAB);
+
+       if (rtstatus != true) {
+               RT_TRACE(COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
+               return false;
+       }
+       rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw,
+                                                       RFPGA0_XA_HSSIPARAMETER2,
+                                                       0x200));
+       return true;
+}
+
+static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i, v1, v2;
+       u32 arraylength;
+       u32 *ptrarray;
+
+       RT_TRACE(COMP_INIT, DBG_TRACE, ("Read rtl8812AE_MAC_REG_Array\n"));
+       arraylength = RTL8812AEMAC_1T_ARRAYLEN;
+       ptrarray = RTL8812AE_MAC_REG_ARRAY;
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("Img:RTL8812AE_MAC_REG_ARRAY LEN %d\n",arraylength));
+       for (i = 0; i < arraylength; i += 2) {
+               v1 = ptrarray[i];
+               v2 = (u8) ptrarray[i + 1];
+               if (v1<0xCDCDCDCD) {
+                       rtl_write_byte(rtlpriv, v1, (u8) v2);
+               } else {
+                       if (!_rtl8821ae_check_condition(hw,v1)) {
+                               /*Discard the following (offset, data) pairs*/
+                               READ_NEXT_PAIR(ptrarray, v1, v2, i);
+                               while (v2 != 0xDEAD &&
+                                          v2 != 0xCDEF &&
+                                          v2 != 0xCDCD && i < arraylength -2)
+                                       READ_NEXT_PAIR(ptrarray, v1, v2, i);
+
+                               i -= 2; /* prevent from for-loop += 2*/
+                       } else {/*Configure matched pairs and skip to end of if-else.*/
+                               READ_NEXT_PAIR(ptrarray, v1, v2, i);
+                               while (v2 != 0xDEAD &&
+                                          v2 != 0xCDEF &&
+                                          v2 != 0xCDCD && i < arraylength -2) {
+                                       rtl_write_byte(rtlpriv,v1,v2);
+                                       READ_NEXT_PAIR(ptrarray, v1, v2, i);
+                               }
+
+                               while (v2 != 0xDEAD && i < arraylength -2)
+                                       READ_NEXT_PAIR(ptrarray, v1, v2, i);
+                       }
+               }
+       }
+       return true;
+}
+
+static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i, v1, v2;
+       u32 arraylength;
+       u32 *ptrarray;
+
+       RT_TRACE(COMP_INIT, DBG_TRACE, ("Read rtl8821AE_MAC_REG_Array\n"));
+       arraylength = RTL8821AEMAC_1T_ARRAYLEN;
+       ptrarray = RTL8821AE_MAC_REG_ARRAY;
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("Img:RTL8821AE_MAC_REG_ARRAY LEN %d\n",arraylength));
+       for (i = 0; i < arraylength; i += 2) {
+               v1 = ptrarray[i];
+               v2 = (u8) ptrarray[i + 1];
+               if (v1<0xCDCDCDCD) {
+                       rtl_write_byte(rtlpriv, v1, (u8) v2);
+                       continue;
+               } else {
+                       if (!_rtl8821ae_check_condition(hw,v1)) {
+                               /*Discard the following (offset, data) pairs*/
+                               READ_NEXT_PAIR(ptrarray, v1, v2, i);
+                               while (v2 != 0xDEAD &&
+                                          v2 != 0xCDEF &&
+                                          v2 != 0xCDCD && i < arraylength -2)
+                                       READ_NEXT_PAIR(ptrarray, v1, v2, i);
+
+                               i -= 2; /* prevent from for-loop += 2*/
+                       } else {/*Configure matched pairs and skip to end of if-else.*/
+                               READ_NEXT_PAIR(ptrarray, v1, v2, i);
+                               while (v2 != 0xDEAD &&
+                                          v2 != 0xCDEF &&
+                                          v2 != 0xCDCD && i < arraylength -2) {
+                                       rtl_write_byte(rtlpriv,v1,v2);
+                                       READ_NEXT_PAIR(ptrarray, v1, v2, i);
+                               }
+
+                               while (v2 != 0xDEAD && i < arraylength -2)
+                                       READ_NEXT_PAIR(ptrarray, v1, v2, i);
+                       }
+               }
+       }
+       return true;
+}
+
+static bool _rtl8812ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+                                                 u8 configtype)
+{
+       int i;
+       u32 *array_table;
+       u16 arraylen;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 v1 = 0, v2 = 0;
+
+       if (configtype == BASEBAND_CONFIG_PHY_REG) {
+               arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
+               array_table = RTL8812AE_PHY_REG_ARRAY;
+
+               for (i = 0; i < arraylen; i += 2) {
+                       v1 = array_table[i];
+                       v2 = array_table[i+1];
+                       if (v1<0xCDCDCDCD) {
+                               _rtl8812ae_config_bb_reg(hw, v1, v2);
+                               continue;
+                       } else {/*This line is the start line of branch.*/
+                               if (!_rtl8821ae_check_condition(hw,v1)) {
+                                       /*Discard the following (offset, data) pairs*/
+                                       READ_NEXT_PAIR(array_table,v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < arraylen -2)
+                                           READ_NEXT_PAIR(array_table,v1, v2, i);
+
+                                       i -= 2; /* prevent from for-loop += 2*/
+                               } else {/*Configure matched pairs and skip to end of if-else.*/
+                                       READ_NEXT_PAIR(array_table,v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < arraylen -2) {
+                                               _rtl8812ae_config_bb_reg(hw,v1,v2);
+                                               READ_NEXT_PAIR(array_table,v1, v2, i);
+                                       }
+
+                                       while (v2 != 0xDEAD && i < arraylen -2)
+                                               READ_NEXT_PAIR(array_table,v1, v2, i);
+                               }
+                       }
+               }
+       } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
+                       arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
+                       array_table = RTL8812AE_AGC_TAB_ARRAY;
+
+                       for (i = 0; i < arraylen; i = i + 2) {
+                               v1 = array_table[i];
+                               v2 = array_table[i+1];
+                               if (v1 < 0xCDCDCDCD) {
+                                       rtl_set_bbreg(hw, v1, MASKDWORD, v2);
+                                       udelay(1);
+                                       continue;
+                           } else {/*This line is the start line of branch.*/
+                                       if (!_rtl8821ae_check_condition(hw,v1)) {
+                                               /*Discard the following (offset, data) pairs*/
+                                               READ_NEXT_PAIR(array_table,v1, v2, i);
+                                               while (v2 != 0xDEAD &&
+                                                      v2 != 0xCDEF &&
+                                                      v2 != 0xCDCD && i < arraylen -2)
+                                                   READ_NEXT_PAIR(array_table,v1, v2, i);
+
+                                               i -= 2; /* prevent from for-loop += 2*/
+                                       }else{/*Configure matched pairs and skip to end of if-else.*/
+                                               READ_NEXT_PAIR(array_table,v1, v2, i);
+                                               while (v2 != 0xDEAD &&
+                                                      v2 != 0xCDEF &&
+                                                      v2 != 0xCDCD && i < arraylen -2)
+                                               {
+                                                       rtl_set_bbreg(hw, v1, MASKDWORD, v2);
+                                                       udelay(1);
+                                                       READ_NEXT_PAIR(array_table,v1, v2, i);
+                                               }
+
+                                               while (v2 != 0xDEAD && i < arraylen -2)
+                                                       READ_NEXT_PAIR(array_table,v1, v2, i);
+                                       }
+                               }
+                               RT_TRACE(COMP_INIT, DBG_TRACE,
+                                ("The agctab_array_table[0] is "
+                                 "%x Rtl818EEPHY_REGArray[1] is %x \n",
+                                 array_table[i],
+                                 array_table[i + 1]));
+               }
+       }
+       return true;
+}
+
+static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+                                                 u8 configtype)
+{
+       int i;
+       u32 *array_table;
+       u16 arraylen;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 v1 = 0, v2 = 0;
+
+       if (configtype == BASEBAND_CONFIG_PHY_REG) {
+               arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
+               array_table = RTL8821AE_PHY_REG_ARRAY;
+
+               for (i = 0; i < arraylen; i += 2) {
+                       v1 = array_table[i];
+                       v2 = array_table[i+1];
+                       if (v1<0xCDCDCDCD) {
+                               _rtl8821ae_config_bb_reg(hw, v1, v2);
+                               continue;
+                       } else {/*This line is the start line of branch.*/
+                               if (!_rtl8821ae_check_condition(hw,v1)) {
+                                       /*Discard the following (offset, data) pairs*/
+                                       READ_NEXT_PAIR(array_table, v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < arraylen -2)
+                                           READ_NEXT_PAIR(array_table, v1, v2, i);
+
+                                       i -= 2; /* prevent from for-loop += 2*/
+                               } else {/*Configure matched pairs and skip to end of if-else.*/
+                                       READ_NEXT_PAIR(array_table, v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < arraylen -2) {
+                                               _rtl8821ae_config_bb_reg(hw,v1,v2);
+                                               READ_NEXT_PAIR(array_table, v1, v2, i);
+                                       }
+
+                                       while (v2 != 0xDEAD && i < arraylen -2)
+                                               READ_NEXT_PAIR(array_table, v1, v2, i);
+                               }
+                       }
+               }
+       } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
+                       arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
+                       array_table = RTL8821AE_AGC_TAB_ARRAY;
+
+                       for (i = 0; i < arraylen; i = i + 2) {
+                               v1 = array_table[i];
+                               v2 = array_table[i+1];
+                               if (v1 < 0xCDCDCDCD) {
+                                       rtl_set_bbreg(hw, v1, MASKDWORD, v2);
+                                       udelay(1);
+                                       continue;
+                           } else {/*This line is the start line of branch.*/
+                                       if (!_rtl8821ae_check_condition(hw,v1)) {
+                                               /*Discard the following (offset, data) pairs*/
+                                               READ_NEXT_PAIR(array_table, v1, v2, i);
+                                               while (v2 != 0xDEAD &&
+                                                      v2 != 0xCDEF &&
+                                                      v2 != 0xCDCD && i < arraylen -2)
+                                                   READ_NEXT_PAIR(array_table, v1, v2, i);
+
+                                               i -= 2; /* prevent from for-loop += 2*/
+                                       }else{/*Configure matched pairs and skip to end of if-else.*/
+                                               READ_NEXT_PAIR(array_table, v1, v2, i);
+                                               while (v2 != 0xDEAD &&
+                                                      v2 != 0xCDEF &&
+                                                      v2 != 0xCDCD && i < arraylen -2)
+                                               {
+                                                       rtl_set_bbreg(hw, v1, MASKDWORD, v2);
+                                                       udelay(1);
+                                                       READ_NEXT_PAIR(array_table, v1, v2, i);
+                                               }
+
+                                               while (v2 != 0xDEAD && i < arraylen -2)
+                                                       READ_NEXT_PAIR(array_table, v1, v2, i);
+                                       }
+                               }
+                               RT_TRACE(COMP_INIT, DBG_TRACE,
+                                ("The agctab_array_table[0] is "
+                                 "%x Rtl818EEPHY_REGArray[1] is %x \n",
+                                 array_table[i],
+                                 array_table[i + 1]));
+               }
+       }
+       return true;
+}
+
+static u8 _rtl8821ae_get_rate_selection_index(u32 regaddr)
+{
+       u8 index = 0;
+
+       regaddr &= 0xFFF;
+       if (regaddr >= 0xC20 && regaddr <= 0xC4C)
+               index = (u8) ((regaddr - 0xC20) / 4);
+       else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
+               index = (u8) ((regaddr - 0xE20) / 4);
+       else
+               RT_ASSERT(!COMP_INIT,
+                       ("Invalid RegAddr 0x%x in"
+                        "PHY_GetRateSectionIndexOfTxPowerByRate()\n",regaddr));
+
+       return index;
+}
+
+static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
+                                                                                                                u32 band, u32 rfpath,
+                                                                                                                u32 txnum, u32 regaddr,
+                                                                                                                u32 bitmask, u32 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 rate_section = _rtl8821ae_get_rate_selection_index(regaddr);
+
+       if (band != BAND_ON_2_4G && band != BAND_ON_5G)
+               RT_TRACE(COMP_INIT, DBG_WARNING, ("Invalid Band %d\n", band));
+
+       if (rfpath > MAX_RF_PATH)
+               RT_TRACE(COMP_INIT, DBG_WARNING, ("Invalid RfPath %d\n", rfpath));
+
+       if (txnum > MAX_RF_PATH)
+               RT_TRACE(COMP_INIT, DBG_WARNING, ("Invalid TxNum %d\n", txnum ) );
+
+       rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
+       RT_TRACE(COMP_INIT, DBG_WARNING,( "pHalData->TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
+                       band, rfpath, txnum, rate_section, rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]));
+
+}
+
+static bool _rtl8812ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+                                                                                                                                        u8 configtype)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i;
+       u32 *phy_regarray_table_pg;
+       u16 phy_regarray_pg_len;
+       u32 v1, v2, v3, v4, v5, v6;
+
+       phy_regarray_pg_len = RTL8812AEPHY_REG_ARRAY_PGLEN;
+       phy_regarray_table_pg = RTL8812AE_PHY_REG_ARRAY_PG;
+
+       if (configtype == BASEBAND_CONFIG_PHY_REG) {
+               for (i = 0; i < phy_regarray_pg_len; i += 6) {
+                       v1 = phy_regarray_table_pg[i];
+                       v2 = phy_regarray_table_pg[i+1];
+                       v3 = phy_regarray_table_pg[i+2];
+                       v4 = phy_regarray_table_pg[i+3];
+                       v5 = phy_regarray_table_pg[i+4];
+                       v6 = phy_regarray_table_pg[i+5];
+
+                       if (v1<0xCDCDCDCD) {
+                               if ( (v4 == 0xfe) || (v4 == 0xffe))
+                                       mdelay(50);
+                               else
+                                       /*_rtl8821ae_store_pwrIndex_diffrate_offset*/
+                                       _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3, v4, v5, v6);
+                               continue;
+                       } else {
+                               if (!_rtl8821ae_check_condition(hw,v1)) { /*don't need the hw_body*/
+                               i += 2; /* skip the pair of expression*/
+                               v1 = phy_regarray_table_pg[i];
+                               v2 = phy_regarray_table_pg[i+1];
+                               v3 = phy_regarray_table_pg[i+2];
+                               while (v2 != 0xDEAD) {
+                                   i += 3;
+                                   v1 = phy_regarray_table_pg[i];
+                                   v2 = phy_regarray_table_pg[i+1];
+                                   v3 = phy_regarray_table_pg[i+2];
+                               }
+                           }
+                       }
+               }
+       } else {
+
+               RT_TRACE(COMP_SEND, DBG_TRACE,
+                        ("configtype != BaseBand_Config_PHY_REG\n"));
+       }
+       return true;
+}
+
+static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+                                                                                                                                        u8 configtype)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i;
+       u32 *phy_regarray_table_pg;
+       u16 phy_regarray_pg_len;
+       u32 v1, v2, v3, v4, v5, v6;
+
+       phy_regarray_pg_len = RTL8821AEPHY_REG_ARRAY_PGLEN;
+       phy_regarray_table_pg = RTL8821AE_PHY_REG_ARRAY_PG;
+
+       if (configtype == BASEBAND_CONFIG_PHY_REG) {
+               for (i = 0; i < phy_regarray_pg_len; i += 6) {
+                       v1 = phy_regarray_table_pg[i];
+                       v2 = phy_regarray_table_pg[i+1];
+                       v3 = phy_regarray_table_pg[i+2];
+                       v4 = phy_regarray_table_pg[i+3];
+                       v5 = phy_regarray_table_pg[i+4];
+                       v6 = phy_regarray_table_pg[i+5];
+
+                       if (v1<0xCDCDCDCD) {
+                               if (v4 == 0xfe)
+                                       mdelay(50);
+                               else if (v4 == 0xfd)
+                                       mdelay(5);
+                               else if (v4 == 0xfc)
+                                       mdelay(1);
+                               else if (v4 == 0xfb)
+                                       udelay(50);
+                               else if (v4 == 0xfa)
+                                       udelay(5);
+                               else if (v4 == 0xf9)
+                                       udelay(1);
+
+                               /*_rtl8821ae_store_pwrIndex_diffrate_offset*/
+                               _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3, v4, v5, v6);
+                               continue;
+                       } else {
+                               if (!_rtl8821ae_check_condition(hw,v1)) { /*don't need the hw_body*/
+                               i += 2; /* skip the pair of expression*/
+                               v1 = phy_regarray_table_pg[i];
+                               v2 = phy_regarray_table_pg[i+1];
+                               v3 = phy_regarray_table_pg[i+2];
+                               while (v2 != 0xDEAD) {
+                                   i += 3;
+                                   v1 = phy_regarray_table_pg[i];
+                                   v2 = phy_regarray_table_pg[i+1];
+                                   v3 = phy_regarray_table_pg[i+2];
+                               }
+                           }
+                       }
+               }
+       } else {
+
+               RT_TRACE(COMP_SEND, DBG_TRACE,
+                        ("configtype != BaseBand_Config_PHY_REG\n"));
+       }
+       return true;
+}
+
+bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw * hw,
+                                                                                                                enum radio_path rfpath)
+{
+       #define READ_NEXT_RF_PAIR_8812(radioa_array_table,v1, v2, i) do { i += 2; v1 = radioa_array_table[i]; v2 = radioa_array_table[i+1]; } while(0)
+
+       int i;
+       bool rtstatus = true;
+       u32 *radioa_array_table_a, *radioa_array_table_b;
+       u16 radioa_arraylen_a, radioa_arraylen_b;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 v1 = 0, v2 = 0;
+
+       radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
+       radioa_array_table_a= RTL8812AE_RADIOA_ARRAY;
+       radioa_arraylen_b= RTL8812AE_RADIOB_1TARRAYLEN;
+       radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("Radio_A:RTL8821AE_RADIOA_ARRAY %d\n",radioa_arraylen_a));
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
+       rtstatus = true;
+       switch (rfpath) {
+       case RF90_PATH_A:
+               for (i = 0; i < radioa_arraylen_a; i = i + 2) {
+                       v1 = radioa_array_table_a[i];
+                       v2 = radioa_array_table_a[i+1];
+                       if (v1<0xcdcdcdcd) {
+                               _rtl8821ae_config_rf_radio_a(hw,v1,v2);
+                               continue;
+                       }else{/*This line is the start line of branch.*/
+                               if(!_rtl8821ae_check_condition(hw,v1)){
+                                       /*Discard the following (offset, data) pairs*/
+                                       READ_NEXT_RF_PAIR_8812(radioa_array_table_a,v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < radioa_arraylen_a-2)
+                                           READ_NEXT_RF_PAIR_8812(radioa_array_table_a,v1, v2, i);
+
+                                       i -= 2; /* prevent from for-loop += 2*/
+                               } else {/*Configure matched pairs and skip to end of if-else.*/
+                                       READ_NEXT_RF_PAIR_8812(radioa_array_table_a,v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < radioa_arraylen_a -2) {
+                                               _rtl8821ae_config_rf_radio_a(hw,v1,v2);
+                                               READ_NEXT_RF_PAIR_8812(radioa_array_table_a,v1, v2, i);
+                                       }
+
+                                       while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
+                                               READ_NEXT_RF_PAIR_8812(radioa_array_table_a,v1, v2, i);
+                               }
+                       }
+               }
+               break;
+       case RF90_PATH_B:
+               for (i = 0; i < radioa_arraylen_b; i = i + 2) {
+                       v1 = radioa_array_table_b[i];
+                       v2 = radioa_array_table_b[i+1];
+                       if (v1<0xcdcdcdcd) {
+                               _rtl8821ae_config_rf_radio_b(hw,v1,v2);
+                               continue;
+                       }else{/*This line is the start line of branch.*/
+                               if(!_rtl8821ae_check_condition(hw,v1)){
+                                       /*Discard the following (offset, data) pairs*/
+                                       READ_NEXT_RF_PAIR_8812(radioa_array_table_b,v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < radioa_arraylen_b-2)
+                                           READ_NEXT_RF_PAIR_8812(radioa_array_table_b,v1, v2, i);
+
+                                       i -= 2; /* prevent from for-loop += 2*/
+                               } else {/*Configure matched pairs and skip to end of if-else.*/
+                                       READ_NEXT_RF_PAIR_8812(radioa_array_table_b,v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < radioa_arraylen_b-2) {
+                                               _rtl8821ae_config_rf_radio_b(hw,v1,v2);
+                                               READ_NEXT_RF_PAIR_8812(radioa_array_table_b,v1, v2, i);
+                                       }
+
+                                       while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
+                                               READ_NEXT_RF_PAIR_8812(radioa_array_table_b,v1, v2, i);
+                               }
+                       }
+               }
+               break;
+       case RF90_PATH_C:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       case RF90_PATH_D:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       }
+       return true;
+}
+
+
+bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw * hw,
+                                                                                                                enum radio_path rfpath)
+{
+       #define READ_NEXT_RF_PAIR(v1, v2, i) do { i += 2; v1 = radioa_array_table[i]; v2 = radioa_array_table[i+1]; } while(0)
+
+       int i;
+       bool rtstatus = true;
+       u32 *radioa_array_table;
+       u16 radioa_arraylen;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       //struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 v1 = 0, v2 = 0;
+
+       radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
+       radioa_array_table = RTL8821AE_RADIOA_ARRAY;
+       RT_TRACE(COMP_INIT, DBG_LOUD,
+                ("Radio_A:RTL8821AE_RADIOA_ARRAY %d\n",radioa_arraylen));
+       RT_TRACE(COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
+       rtstatus = true;
+       switch (rfpath) {
+       case RF90_PATH_A:
+               for (i = 0; i < radioa_arraylen; i = i + 2) {
+                       v1 = radioa_array_table[i];
+                       v2 = radioa_array_table[i+1];
+                       if (v1<0xcdcdcdcd) {
+                               _rtl8821ae_config_rf_radio_a(hw,v1,v2);
+                       }else{/*This line is the start line of branch.*/
+                               if(!_rtl8821ae_check_condition(hw,v1)){
+                                       /*Discard the following (offset, data) pairs*/
+                                       READ_NEXT_RF_PAIR(v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < radioa_arraylen -2)
+                                           READ_NEXT_RF_PAIR(v1, v2, i);
+
+                                       i -= 2; /* prevent from for-loop += 2*/
+                               } else {/*Configure matched pairs and skip to end of if-else.*/
+                                       READ_NEXT_RF_PAIR(v1, v2, i);
+                                       while (v2 != 0xDEAD &&
+                                              v2 != 0xCDEF &&
+                                              v2 != 0xCDCD && i < radioa_arraylen -2) {
+                                               _rtl8821ae_config_rf_radio_a(hw,v1,v2);
+                                               READ_NEXT_RF_PAIR(v1, v2, i);
+                                       }
+
+                                       while (v2 != 0xDEAD && i < radioa_arraylen -2)
+                                               READ_NEXT_RF_PAIR(v1, v2, i);
+                               }
+                       }
+               }
+               break;
+
+       case RF90_PATH_B:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       case RF90_PATH_C:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       case RF90_PATH_D:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       }
+       return true;
+}
+
+void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       rtlphy->default_initialgain[0] =
+           (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
+       rtlphy->default_initialgain[1] =
+           (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
+       rtlphy->default_initialgain[2] =
+           (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
+       rtlphy->default_initialgain[3] =
+           (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
+
+       RT_TRACE(COMP_INIT, DBG_TRACE,
+                ("Default initial gain (c50=0x%x, "
+                 "c58=0x%x, c60=0x%x, c68=0x%x \n",
+                 rtlphy->default_initialgain[0],
+                 rtlphy->default_initialgain[1],
+                 rtlphy->default_initialgain[2],
+                 rtlphy->default_initialgain[3]));
+
+       rtlphy->framesync = (u8) rtl_get_bbreg(hw,
+                                              ROFDM0_RXDETECTOR3, MASKBYTE0);
+       rtlphy->framesync_c34 = rtl_get_bbreg(hw,
+                                             ROFDM0_RXDETECTOR2, MASKDWORD);
+
+       RT_TRACE(COMP_INIT, DBG_TRACE,
+                ("Default framesync (0x%x) = 0x%x \n",
+                 ROFDM0_RXDETECTOR3, rtlphy->framesync));
+}
+
+static void _rtl8821ae_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+       rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+
+       rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
+       rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
+
+       rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
+       rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
+
+       rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
+       rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
+
+       rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
+       rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
+
+       rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = RA_SIREAD_8821A;
+       rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = RB_SIREAD_8821A;
+
+       rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = RA_PIREAD_8821A;
+       rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = RB_PIREAD_8821A;
+}
+
+void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 txpwr_level;
+       long txpwr_dbm;
+
+       txpwr_level = rtlphy->cur_cck_txpwridx;
+       txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
+                                                WIRELESS_MODE_B, txpwr_level);
+       txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
+       if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
+                                        WIRELESS_MODE_G,
+                                        txpwr_level) > txpwr_dbm)
+               txpwr_dbm =
+                   _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
+                                                txpwr_level);
+       txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
+       if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
+                                        WIRELESS_MODE_N_24G,
+                                        txpwr_level) > txpwr_dbm)
+               txpwr_dbm =
+                   _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
+                                                txpwr_level);
+       *powerlevel = txpwr_dbm;
+}
+
+static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
+{
+       u8 channel_5g[CHANNEL_MAX_NUMBER_5G] =
+                                {36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,100,102,104,106,108,110,112,
+                               114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,149,151,
+                               153,155,157,159,161,163,165,167,168,169,171,173,175,177};
+       u8 i = 0;
+       bool in_24g = true;
+
+       if (channel <= 14) {
+               in_24g = true;
+               *chnl_index = channel - 1;
+       } else {
+               in_24g = false;
+
+               for (i = 0; i < sizeof(channel_5g) / sizeof(u8); ++i) {
+                       if (channel_5g[i] == channel) {
+                               *chnl_index = i;
+                               return in_24g;
+                       }
+               }
+       }
+       return in_24g;
+}
+
+static char _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
+{
+       char rate_section = 0;
+       switch (rate) {
+       case DESC_RATE1M:
+       case DESC_RATE2M:
+       case DESC_RATE5_5M:
+       case DESC_RATE11M:
+               rate_section = 0;
+               break;
+
+       case DESC_RATE6M:
+       case DESC_RATE9M:
+       case DESC_RATE12M:
+       case DESC_RATE18M:
+               rate_section = 1;
+               break;
+
+       case DESC_RATE24M:
+       case DESC_RATE36M:
+       case DESC_RATE48M:
+       case DESC_RATE54M:
+               rate_section = 2;
+               break;
+
+       case DESC_RATEMCS0:
+       case DESC_RATEMCS1:
+       case DESC_RATEMCS2:
+       case DESC_RATEMCS3:
+               rate_section = 3;
+               break;
+
+       case DESC_RATEMCS4:
+       case DESC_RATEMCS5:
+       case DESC_RATEMCS6:
+       case DESC_RATEMCS7:
+               rate_section = 4;
+               break;
+
+       case DESC_RATEMCS8:
+       case DESC_RATEMCS9:
+       case DESC_RATEMCS10:
+       case DESC_RATEMCS11:
+               rate_section = 5;
+               break;
+
+       case DESC_RATEMCS12:
+       case DESC_RATEMCS13:
+       case DESC_RATEMCS14:
+       case DESC_RATEMCS15:
+               rate_section = 6;
+               break;
+
+       case DESC_RATEVHT1SS_MCS0:
+       case DESC_RATEVHT1SS_MCS1:
+       case DESC_RATEVHT1SS_MCS2:
+       case DESC_RATEVHT1SS_MCS3:
+               rate_section = 7;
+               break;
+
+       case DESC_RATEVHT1SS_MCS4:
+       case DESC_RATEVHT1SS_MCS5:
+       case DESC_RATEVHT1SS_MCS6:
+       case DESC_RATEVHT1SS_MCS7:
+               rate_section = 8;
+               break;
+
+       case DESC_RATEVHT1SS_MCS8:
+       case DESC_RATEVHT1SS_MCS9:
+       case DESC_RATEVHT2SS_MCS0:
+       case DESC_RATEVHT2SS_MCS1:
+               rate_section = 9;
+               break;
+
+       case DESC_RATEVHT2SS_MCS2:
+       case DESC_RATEVHT2SS_MCS3:
+       case DESC_RATEVHT2SS_MCS4:
+       case DESC_RATEVHT2SS_MCS5:
+               rate_section = 10;
+               break;
+
+       case DESC_RATEVHT2SS_MCS6:
+       case DESC_RATEVHT2SS_MCS7:
+       case DESC_RATEVHT2SS_MCS8:
+       case DESC_RATEVHT2SS_MCS9:
+               rate_section = 11;
+               break;
+
+       default:
+               RT_ASSERT(true, ("Rate_Section is Illegal\n"));
+               break;
+       }
+
+       return rate_section;
+}
+
+static char _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
+                                                                                                                  u8 band, u8 path, u8 rate)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 shift = 0, rate_section, tx_num;
+       char tx_pwr_diff = 0;
+
+       rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
+       tx_num = RF_TX_NUM_NONIMPLEMENT;
+
+       if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
+               if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15 ) ||
+                       (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
+                        tx_num = RF_2TX;
+               else
+                       tx_num = RF_1TX;
+       }
+
+       switch (rate) {
+       case DESC_RATE1M:       shift = 0;              break;
+       case DESC_RATE2M:       shift = 8;              break;
+       case DESC_RATE5_5M:     shift = 16;             break;
+       case DESC_RATE11M:      shift = 24;             break;
+
+       case DESC_RATE6M:       shift = 0;              break;
+       case DESC_RATE9M:       shift = 8;      break;
+       case DESC_RATE12M:      shift = 16;     break;
+       case DESC_RATE18M:      shift = 24;     break;
+
+       case DESC_RATE24M:      shift = 0;      break;
+       case DESC_RATE36M:      shift = 8;      break;
+       case DESC_RATE48M:      shift = 16;     break;
+       case DESC_RATE54M:      shift = 24;     break;
+
+       case DESC_RATEMCS0:     shift = 0;              break;
+       case DESC_RATEMCS1:     shift = 8;      break;
+       case DESC_RATEMCS2:     shift = 16;     break;
+       case DESC_RATEMCS3:     shift = 24;     break;
+
+       case DESC_RATEMCS4:     shift = 0;              break;
+       case DESC_RATEMCS5:     shift = 8;      break;
+       case DESC_RATEMCS6:     shift = 16;     break;
+       case DESC_RATEMCS7:     shift = 24;     break;
+
+       case DESC_RATEMCS8:     shift = 0;              break;
+       case DESC_RATEMCS9:     shift = 8;      break;
+       case DESC_RATEMCS10:    shift = 16;     break;
+       case DESC_RATEMCS11:    shift = 24;     break;
+
+       case DESC_RATEMCS12:    shift = 0;              break;
+       case DESC_RATEMCS13:    shift = 8;      break;
+       case DESC_RATEMCS14:    shift = 16;     break;
+       case DESC_RATEMCS15:    shift = 24;     break;
+
+       case DESC_RATEVHT1SS_MCS0:      shift = 0;              break;
+       case DESC_RATEVHT1SS_MCS1:      shift = 8;      break;
+       case DESC_RATEVHT1SS_MCS2:      shift = 16;     break;
+       case DESC_RATEVHT1SS_MCS3:      shift = 24;     break;
+
+       case DESC_RATEVHT1SS_MCS4:      shift = 0;              break;
+       case DESC_RATEVHT1SS_MCS5:      shift = 8;      break;
+       case DESC_RATEVHT1SS_MCS6:      shift = 16;     break;
+       case DESC_RATEVHT1SS_MCS7:      shift = 24;     break;
+
+       case DESC_RATEVHT1SS_MCS8:      shift = 0;              break;
+       case DESC_RATEVHT1SS_MCS9:      shift = 8;      break;
+       case DESC_RATEVHT2SS_MCS0:      shift = 16;     break;
+       case DESC_RATEVHT2SS_MCS1:      shift = 24;     break;
+
+       case DESC_RATEVHT2SS_MCS2:      shift = 0;              break;
+       case DESC_RATEVHT2SS_MCS3:      shift = 8;      break;
+       case DESC_RATEVHT2SS_MCS4:      shift = 16;     break;
+       case DESC_RATEVHT2SS_MCS5:      shift = 24;     break;
+
+       case DESC_RATEVHT2SS_MCS6:      shift = 0;              break;
+       case DESC_RATEVHT2SS_MCS7:      shift = 8;      break;
+       case DESC_RATEVHT2SS_MCS8:      shift = 16;     break;
+       case DESC_RATEVHT2SS_MCS9:      shift = 24;     break;
+
+       default:
+               RT_ASSERT(true, ("Rate_Section is Illegal\n"));
+               break;
+       }
+
+       tx_pwr_diff = (u8) (rtlphy->tx_power_by_rate_offset[band][path][tx_num][rate_section] >> shift) & 0xff;
+
+       return  tx_pwr_diff;
+}
+
+static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
+                                                                                        u8 rate, u8 bandwidth, u8 channel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 index = (channel - 1);
+       u8 txpower = 0;
+       bool in_24g = false;
+       char powerdiff_byrate = 0;
+
+       if (((rtlhal->current_bandtype == BAND_ON_2_4G) && (channel > 14 || channel < 1)) ||
+               ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
+               index = 0;
+               RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("Illegal channel!!\n"));
+       }
+
+       in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
+       if (in_24g) {
+               if (RX_HAL_IS_CCK_RATE(rate))
+                       txpower = rtlefuse->txpwrlevel_cck[path][index];
+               else if ( DESC_RATE6M <= rate )
+                       txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
+               else
+                       RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("invalid rate\n"));
+
+               if (DESC_RATE6M <= rate && rate <= DESC_RATE54M && !RX_HAL_IS_CCK_RATE(rate))
+                       txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
+
+               if (bandwidth == HT_CHANNEL_WIDTH_20) {
+                       if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                               txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
+                       if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                               txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
+               } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
+                       if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                               txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
+                       if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                               txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
+               } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
+                       if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                               txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
+                       if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                               txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
+               }
+
+       } else {
+               if (DESC_RATE6M <= rate)
+                       txpower = rtlefuse->txpwr_5g_bw40base[path][index];
+           else
+               RT_TRACE(COMP_POWER_TRACKING, DBG_WARNING,("INVALID Rate.\n"));
+
+        if (DESC_RATE6M <= rate && rate <= DESC_RATE54M && !RX_HAL_IS_CCK_RATE(rate))
+               txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
+
+           if (bandwidth == HT_CHANNEL_WIDTH_20) {
+               if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                   txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
+               if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                   txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
+           } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
+               if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                   txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
+               if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                   txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
+           } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
+                       u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, 138, 155, 171};
+                       u8 i = 0;
+                       for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i)
+                               if (channel_5g_80m[i] == channel)
+                                       index = i;
+
+               if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                   txpower = rtlefuse->txpwr_5g_bw80base[path][index]
+                               + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
+               if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
+                               (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
+                   txpower = rtlefuse->txpwr_5g_bw80base[path][index]
+                               + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
+                               + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
+           }
+       }
+       if (rtlefuse->eeprom_regulatory != 2)
+               powerdiff_byrate = _rtl8821ae_phy_get_txpower_by_rate(hw,
+                                                                       (u8)(!in_24g), path, rate);
+
+       if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
+               rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
+               txpower -= powerdiff_byrate;
+       else
+               txpower += powerdiff_byrate;
+
+       if (rate > DESC_RATE11M)
+               txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
+       else
+               txpower += rtlpriv->dm.remnant_cck_idx;
+
+       if (txpower > MAX_POWER_INDEX)
+               txpower = MAX_POWER_INDEX;
+
+       return txpower;
+}
+
+static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
+                                                                                               u8 power_index, u8 path, u8 rate)
+{
+       struct rtl_priv* rtlpriv = rtl_priv(hw);
+
+       if (path == RF90_PATH_A) {
+        switch (rate) {
+        case DESC_RATE1M:
+               rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, MASKBYTE0, power_index);
+               break;
+        case DESC_RATE2M:
+               rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, MASKBYTE1, power_index);
+               break;
+        case DESC_RATE5_5M:
+               rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, MASKBYTE2, power_index);
+               break;
+        case DESC_RATE11M:
+               rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, MASKBYTE3, power_index);
+               break;
+
+        case DESC_RATE6M:
+               rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, MASKBYTE0, power_index);
+               break;
+        case DESC_RATE9M:
+               rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, MASKBYTE1, power_index);
+               break;
+        case DESC_RATE12M:
+               rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, MASKBYTE2, power_index);
+               break;
+        case DESC_RATE18M:
+               rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, MASKBYTE3, power_index);
+               break;
+
+        case DESC_RATE24M:
+               rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, MASKBYTE0, power_index);
+               break;
+        case DESC_RATE36M:
+               rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, MASKBYTE1, power_index);
+               break;
+        case DESC_RATE48M:
+               rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, MASKBYTE2, power_index);
+               break;
+        case DESC_RATE54M:
+               rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, MASKBYTE3, power_index);
+               break;
+
+        case DESC_RATEMCS0:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE0, power_index);
+               break;
+        case DESC_RATEMCS1:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE1, power_index);
+               break;
+        case DESC_RATEMCS2:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE2, power_index);
+               break;
+        case DESC_RATEMCS3:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE3, power_index);
+               break;
+
+        case DESC_RATEMCS4:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE0, power_index);
+               break;
+        case DESC_RATEMCS5:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE1, power_index);
+               break;
+        case DESC_RATEMCS6:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE2, power_index);
+               break;
+        case DESC_RATEMCS7:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE3, power_index);
+               break;
+
+        case DESC_RATEMCS8:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE0, power_index);
+               break;
+        case DESC_RATEMCS9:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE1, power_index);
+               break;
+        case DESC_RATEMCS10:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE2, power_index);
+               break;
+        case DESC_RATEMCS11:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE3, power_index);
+               break;
+
+        case DESC_RATEMCS12:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE0, power_index);
+               break;
+        case DESC_RATEMCS13:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE1, power_index);
+               break;
+        case DESC_RATEMCS14:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE2, power_index);
+               break;
+        case DESC_RATEMCS15:
+               rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT1SS_MCS0:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS1:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS2:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS3:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT1SS_MCS4:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS5:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS6:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS7:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT1SS_MCS8:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS9:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS0:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS1:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT2SS_MCS2:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS3:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS4:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS5:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT2SS_MCS6:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS7:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS8:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS9:
+               rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, MASKBYTE3, power_index);
+               break;
+
+        default:
+                       RT_TRACE(COMP_POWER, DBG_LOUD, ("Invalid Rate!!\n"));
+            break;
+        }
+    } else if (path == RF90_PATH_B) {
+       switch (rate) {
+       case DESC_RATE1M:
+               rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, MASKBYTE0, power_index);
+               break;
+       case DESC_RATE2M:
+               rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, MASKBYTE1, power_index);
+               break;
+       case DESC_RATE5_5M:
+               rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, MASKBYTE2, power_index);
+               break;
+       case DESC_RATE11M:
+               rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATE6M:
+               rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, MASKBYTE0, power_index);
+               break;
+       case DESC_RATE9M:
+               rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, MASKBYTE1, power_index);
+               break;
+       case DESC_RATE12M:
+               rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, MASKBYTE2, power_index);
+               break;
+       case DESC_RATE18M:
+               rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATE24M:
+               rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, MASKBYTE0, power_index);
+               break;
+       case DESC_RATE36M:
+               rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, MASKBYTE1, power_index);
+               break;
+       case DESC_RATE48M:
+               rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, MASKBYTE2, power_index);
+               break;
+       case DESC_RATE54M:
+               rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEMCS0:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEMCS1:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEMCS2:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEMCS3:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEMCS4:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEMCS5:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEMCS6:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEMCS7:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEMCS8:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEMCS9:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEMCS10:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEMCS11:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEMCS12:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEMCS13:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEMCS14:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEMCS15:
+               rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT1SS_MCS0:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS1:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS2:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS3:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT1SS_MCS4:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS5:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS6:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS7:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT1SS_MCS8:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT1SS_MCS9:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS0:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS1:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT2SS_MCS2:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS3:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS4:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS5:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, MASKBYTE3, power_index);
+               break;
+
+       case DESC_RATEVHT2SS_MCS6:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, MASKBYTE0, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS7:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, MASKBYTE1, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS8:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, MASKBYTE2, power_index);
+               break;
+       case DESC_RATEVHT2SS_MCS9:
+               rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, MASKBYTE3, power_index);
+               break;
+
+       default:
+               RT_TRACE(COMP_POWER, DBG_LOUD, ("Invalid Rate!!\n"));
+               break;
+        }
+    } else {
+               RT_TRACE(COMP_POWER, DBG_LOUD, ("Invalid RFPath!!\n"));
+    }
+}
+
+void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
+                                                                                                       u8 *array, u8 path, u8 channel,
+                                                                                                       u8 size)
+{
+       struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy);
+       u8 i;
+       u8 power_index;
+       for (i = 0; i < size; i ++) {
+               power_index = _rtl8821ae_get_txpower_index(hw, path, array[i],
+                                                                       rtlphy->current_chan_bw, channel);
+               _rtl8821ae_phy_set_txpower_index(hw, power_index, path, array[i]);
+       }
+}
+
+static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
+                                                                                                               u8 bw, u8 channel, u8 path)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       u8 i;
+       u32 power_level, data, offset;
+
+       if(path >= rtlphy->num_total_rfpath)
+               return;
+
+       data = 0;
+       if (path == RF90_PATH_A) {
+               power_level =
+                       _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
+                       DESC_RATEMCS7, bw, channel);
+               offset =  RA_TXPWRTRAING;
+       } else {
+               power_level =
+                       _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
+                       DESC_RATEMCS7, bw, channel);
+               offset =  RB_TXPWRTRAING;
+       }
+
+       for (i = 0; i < 3; i++) {
+               if (i == 0)
+                       power_level = power_level - 10;
+               else if (i == 1)
+                       power_level = power_level - 8;
+               else
+                       power_level = power_level - 6;
+
+               data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
+       }
+       rtl_set_bbreg(hw, offset, 0xffffff, data);
+}
+
+void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, u8 channel, u8 path)
+{
+       //struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy);
+       u8 cck_rates[]  = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M};
+       u8 ofdm_rates[]  = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, DESC_RATE18M,
+                                               DESC_RATE24M, DESC_RATE36M, DESC_RATE48M, DESC_RATE54M};
+       u8 ht_rates_1t[]  = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, DESC_RATEMCS3,
+                                                DESC_RATEMCS4, DESC_RATEMCS5, DESC_RATEMCS6, DESC_RATEMCS7};
+       u8 ht_rates_2t[]  = {DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, DESC_RATEMCS11,
+                                                DESC_RATEMCS12, DESC_RATEMCS13, DESC_RATEMCS14, DESC_RATEMCS15};
+       u8 vht_rates_1t[]  = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, DESC_RATEVHT1SS_MCS2,
+                                               DESC_RATEVHT1SS_MCS3, DESC_RATEVHT1SS_MCS4,
+                                                 DESC_RATEVHT1SS_MCS5, DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
+                                                 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
+       u8 vht_rates_2t[]  = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, DESC_RATEVHT2SS_MCS2,
+                                               DESC_RATEVHT2SS_MCS3, DESC_RATEVHT2SS_MCS4,
+                                                 DESC_RATEVHT2SS_MCS5, DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
+                                                 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
+       //u8 i,size;
+       //u8 power_index;
+
+       if (rtlhal->current_bandtype == BAND_ON_2_4G)
+               _rtl8821ae_phy_set_txpower_level_by_path(hw,cck_rates,path,channel,
+                                                        sizeof(cck_rates) / sizeof(u8));
+
+       _rtl8821ae_phy_set_txpower_level_by_path(hw,ofdm_rates,path,channel,
+                                                    sizeof(ofdm_rates) / sizeof(u8));
+       _rtl8821ae_phy_set_txpower_level_by_path(hw,ht_rates_1t,path,channel,
+                                                    sizeof(ht_rates_1t) / sizeof(u8));
+       _rtl8821ae_phy_set_txpower_level_by_path(hw,vht_rates_1t,path,channel,
+                                                    sizeof(vht_rates_1t) / sizeof(u8));
+
+       if (rtlphy->num_total_rfpath >= 2) {
+               _rtl8821ae_phy_set_txpower_level_by_path(hw,ht_rates_2t,path,channel,
+                                                            sizeof(ht_rates_2t) / sizeof(u8));
+               _rtl8821ae_phy_set_txpower_level_by_path(hw,vht_rates_2t,path,channel,
+                                                            sizeof(vht_rates_2t) / sizeof(u8));
+       }
+
+       _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw, channel, path);
+}
+/*just in case, write txpower in DW, to reduce time*/
+#if 0
+void _rtl8821ae_phy_get_txpower_index_by_rate_array(struct ieee80211_hw *hw, u8 channel,
+                                                                                       u8 *rate, u8 path, u8 bw, u8 *power_index, u8 size)
+{
+       u8 i;
+       for (i = 0; i < size; i++)
+               power_index[i] = _rtl8821ae_get_txpower_index(hw, path, rate[i], bw, channel);
+}
+
+void rtl8821ae_phy_set_txpower_level_by_path2(struct ieee80211_hw *hw, u8 channel, u8 path)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy);
+       u8 cck_rates[]  = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M};
+       u8 ofdm_rates[]  = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, DESC_RATE18M,
+                                               DESC_RATE24M, DESC_RATE36M, DESC_RATE48M, DESC_RATE54M};
+       u8 ht_rates_1t[]  = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, DESC_RATEMCS3,
+                                                DESC_RATEMCS4, DESC_RATEMCS5, DESC_RATEMCS6, DESC_RATEMCS7};
+       u8 ht_rates_2t[]  = {DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, DESC_RATEMCS11,
+                                                DESC_RATEMCS12, DESC_RATEMCS13, DESC_RATEMCS14, DESC_RATEMCS15};
+       u8 vht_rates_1t[]  = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, DESC_RATEVHT1SS_MCS4,
+                                                 DESC_RATEVHT1SS_MCS5, DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
+       u8 vht_rates_2t[]  = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, DESC_RATEVHT2SS_MCS4,
+                                                 DESC_RATEVHT2SS_MCS5, DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
+       u8 i, j;
+       u8 pwridx[48] = {0};
+       u8 cs = sizeof(cck_rates) / sizeof(u8);
+       u8 os = sizeof(ofdm_rates) / sizeof(u8);
+       u8 h1s = sizeof(ht_rates_1t) / sizeof(u8);
+       u8 h2s = sizeof(ht_rates_2t) / sizeof(u8);
+       u8 v1s = sizeof(vht_rates_1t) / sizeof(u8);
+       u8 v2s = sizeof(vht_rates_2t) / sizeof(u8);
+
+       u8 len, start;
+       u32 reg_addr, power_index;
+       u8 bw = rtlphy->current_chan_bw;
+
+       _rtl8821ae_phy_get_txpower_index_by_rate_array(hw, channel,
+               ofdm_rates, path, bw, &pwridx[cs], os);
+
+       _rtl8821ae_phy_get_txpower_index_by_rate_array(hw, channel,
+               ht_rates_1t, path, bw, &pwridx[cs+os], h1s);
+
+       _rtl8821ae_phy_get_txpower_index_by_rate_array(hw, channel,
+               vht_rates_1t, path, bw, &pwridx[cs+os+h1s+h2s], v1s);
+
+
+       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+               _rtl8821ae_phy_get_txpower_index_by_rate_array(hw, channel,
+                       cck_rates, path, bw, pwridx, cs);
+
+               start = 0;
+       } else {
+               start = cs;
+       }
+
+       reg_addr = (path == 0) ? RTXAGC_A_CCK11_CCK1 : RTXAGC_B_CCK11_CCK1;
+       reg_addr += start;
+
+       len = cs + os + h1s + h2s + v1s;
+       if (rtlphy->num_total_rfpath >= 2) {
+               _rtl8821ae_phy_get_txpower_index_by_rate_array(hw, channel,
+                       ht_rates_2t, path, bw, &pwridx[cs+os+h1s], h2s);
+
+               _rtl8821ae_phy_get_txpower_index_by_rate_array(hw, channel,
+                       vht_rates_2t, path, bw, &pwridx[cs+os+h1s+h2s+v1s], v2s);
+
+               len += v2s;
+       }
+       for (i = start; i < len; i += 4) {
+               power_index = 0;
+               for (j = 0; j < 4; j++)
+                       power_index |= (pwridx[i+j] << (j*8));
+               rtl_set_bbreg(hw, reg_addr + i, MASKDWORD, power_index);
+       }
+
+       _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw, channel, path);
+}
+#endif
+
+void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 path = 0;
+
+       for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path )
+               rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
+}
+
+static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
+                                        enum wireless_mode wirelessmode,
+                                        u8 txpwridx)
+{
+       long offset;
+       long pwrout_dbm;
+
+       switch (wirelessmode) {
+       case WIRELESS_MODE_B:
+               offset = -7;
+               break;
+       case WIRELESS_MODE_G:
+       case WIRELESS_MODE_N_24G:
+               offset = -8;
+               break;
+       default:
+               offset = -8;
+               break;
+       }
+       pwrout_dbm = txpwridx / 2 + offset;
+       return pwrout_dbm;
+}
+
+void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
+
+       if (!is_hal_stop(rtlhal)) {
+               switch (operation) {
+               case SCAN_OPT_BACKUP_BAND0:
+                       iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                     HW_VAR_IO_CMD,
+                                                     (u8 *) & iotype);
+
+                       break;
+               case SCAN_OPT_BACKUP_BAND1:
+                       iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                     HW_VAR_IO_CMD,
+                                                     (u8 *) & iotype);
+
+                       break;
+               case SCAN_OPT_RESTORE:
+                       iotype = IO_CMD_RESUME_DM_BY_SCAN;
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                     HW_VAR_IO_CMD,
+                                                     (u8 *) & iotype);
+                       break;
+               default:
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                                ("Unknown Scan Backup operation.\n"));
+                       break;
+               }
+       }
+}
+
+static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv * rtlpriv, u8 bw)
+{
+       u16 reg_rf_mode_bw, tmp = 0;
+       reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
+       switch (bw) {
+       case HT_CHANNEL_WIDTH_20:
+               rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
+               break;
+       case HT_CHANNEL_WIDTH_20_40:
+               tmp = reg_rf_mode_bw | BIT(7);
+               rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
+               break;
+       case HT_CHANNEL_WIDTH_80:
+               tmp = reg_rf_mode_bw | BIT(8);
+               rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_WARNING,("unknown Bandwidth: 0x%x\n",bw));
+               break;
+       }
+}
+
+static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv * rtlpriv)
+{
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtlpriv);
+       u8 sc_set_40 = 0, sc_set_20 =0;
+
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
+               if(mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
+                       sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
+               else if(mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
+                       sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
+               else
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                               ("SCMapping: Not Correct Primary40MHz Setting \n"));
+
+               if((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
+                       (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
+                       sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
+               else if((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
+                       (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
+                       sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
+               else if((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
+                       (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
+                       sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
+               else if((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
+                       (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
+                       sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
+               else
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                               ("SCMapping: Not Correct Primary40MHz Setting \n"));
+       } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+               if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
+                       sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
+               else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
+                       sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
+               else
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("SCMapping: Not Correct Primary40MHz Setting \n"));
+       }
+       return ((sc_set_40 << 4) | sc_set_20);
+}
+
+void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 sub_chnl = 0;
+       u8 l1pk_val = 0;
+
+       RT_TRACE(COMP_SCAN, DBG_TRACE,
+                ("Switch to %s bandwidth\n",
+                 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+                 "20MHz" :
+                 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
+                 "40MHz" : "80MHz"))))
+
+
+
+       _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
+       sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
+       rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
+
+       switch (rtlphy->current_chan_bw) {
+       case HT_CHANNEL_WIDTH_20:
+               rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
+               rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
+
+               if(rtlphy->rf_type == RF_2T2R)
+                       rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
+               else
+                       rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
+               break;
+       case HT_CHANNEL_WIDTH_20_40:
+               rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
+               rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
+               rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
+               rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
+
+               if(rtlphy->reg_837 & BIT(2))
+                       l1pk_val = 6;
+               else
+               {
+                       if(rtlphy->rf_type == RF_2T2R)
+                               l1pk_val = 7;
+                       else
+                               l1pk_val = 8;
+               }
+               rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);     // 0x848[25:22] = 0x6
+
+               if(sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
+                       rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
+               else
+                       rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
+               break;
+
+       case HT_CHANNEL_WIDTH_80:
+               rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202); // 0x8ac[21,20,9:6,1,0]=8'b11100010
+               rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);                    // 0x8c4[30] = 1
+               rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
+               rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
+
+               if(rtlphy->reg_837 & BIT(2))
+                       l1pk_val = 5;
+               else
+               {
+                       if(rtlphy->rf_type == RF_2T2R)
+                               l1pk_val = 6;
+                       else
+                               l1pk_val = 7;
+               }
+               rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
+
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+               break;
+       }
+
+       rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
+
+       rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
+       rtlphy->set_bwmode_inprogress = false;
+
+       RT_TRACE(COMP_SCAN, DBG_LOUD, (" \n"));
+}
+
+void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
+                           enum nl80211_channel_type ch_type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 tmp_bw = rtlphy->current_chan_bw;
+
+       if (rtlphy->set_bwmode_inprogress)
+               return;
+       rtlphy->set_bwmode_inprogress = true;
+       if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
+               rtl8821ae_phy_set_bw_mode_callback(hw);
+       } else {
+               RT_TRACE(COMP_ERR, DBG_WARNING,
+                        ("FALSE driver sleep or unload\n"));
+               rtlphy->set_bwmode_inprogress = false;
+               rtlphy->current_chan_bw = tmp_bw;
+       }
+}
+
+void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 channel = rtlphy->current_channel;
+       u8 path;
+       u32 data;
+
+       RT_TRACE(COMP_SCAN, DBG_TRACE,
+                ("switch to channel%d\n", rtlphy->current_channel));
+       if (is_hal_stop(rtlhal))
+               return;
+
+       if (36 <= channel && channel <= 48)
+               data = 0x494;
+       else if (50 <= channel && channel <= 64)
+               data = 0x453;
+       else if (100 <= channel && channel <= 116)
+               data = 0x452;
+       else if (118 <= channel)
+               data = 0x412;
+       else
+               data = 0x96a;
+       rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
+
+
+       for(path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++)
+       {
+               if (36 <= channel && channel <= 64)
+                       data = 0x101;
+               else if (100 <= channel && channel <= 140)
+                       data = 0x301;
+               else if (140 < channel)
+                       data = 0x501;
+               else
+                       data = 0x000;
+               rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
+                       BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
+
+               rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
+                       BMASKBYTE0, channel);
+
+               if (channel > 14) {
+                       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
+                               if (36 <= channel && channel <= 64)
+                                       data = 0x114E9;
+                               else if (100 <= channel && channel <= 140)
+                                       data = 0x110E9;
+                               else
+                                       data = 0x110E9;
+                               rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
+                                       BRFREGOFFSETMASK, data);
+                       }
+               }
+       }
+       RT_TRACE(COMP_SCAN, DBG_TRACE, ("\n"));
+}
+
+u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 timeout = 1000, timecount = 0;
+       u8 channel = rtlphy->current_channel;
+
+       if (rtlphy->sw_chnl_inprogress)
+               return 0;
+       if (rtlphy->set_bwmode_inprogress)
+               return 0;
+
+       if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
+               RT_TRACE(COMP_CHAN, DBG_LOUD,
+                        ("sw_chnl_inprogress false driver sleep or unload\n"));
+               return 0;
+       }
+       while (rtlphy->lck_inprogress && timecount < timeout) {
+               mdelay(50);
+               timecount += 50;
+       }
+
+       if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
+               rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
+       else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
+               rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
+
+       rtlphy->sw_chnl_inprogress = true;
+       if (channel == 0)
+               channel = 1;
+
+       RT_TRACE(COMP_SCAN, DBG_TRACE,
+                ("switch to channel%d, band type is %d\n", rtlphy->current_channel, rtlhal->current_bandtype));
+
+       rtl8821ae_phy_sw_chnl_callback(hw);
+
+       rtl8821ae_dm_clear_txpower_tracking_state(hw);
+       rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
+
+       RT_TRACE(COMP_SCAN, DBG_TRACE, ("\n"));
+       rtlphy->sw_chnl_inprogress = false;
+       return 1;
+}
+
+#if 0
+static u8 _rtl8821ae_phy_path_b_iqk(struct ieee80211_hw *hw)
+{
+       u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
+       u8 result = 0x00;
+
+       rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
+       rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
+       mdelay(IQK_DELAY_TIME);
+       reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
+       reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
+       reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
+       reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
+       reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
+
+       if (!(reg_eac & BIT(31)) &&
+           (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
+           (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
+               result |= 0x01;
+       else
+               return result;
+       if (!(reg_eac & BIT(30)) &&
+           (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
+           (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
+               result |= 0x02;
+       return result;
+}
+
+static u8 _rtl8821ae_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
+{
+       u32 reg_eac, reg_e94, reg_e9c, reg_ea4,u32temp;
+       u8 result = 0x00;
+
+       /*Get TXIMR Setting*/
+       /*Modify RX IQK mode table*/
+       rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
+       rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
+       rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
+       rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
+       rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
+       rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
+
+       /*IQK Setting*/
+       rtl_set_bbreg(hw, RTx_IQK, MASKDWORD, 0x01007c00);
+       rtl_set_bbreg(hw, RRx_IQK, MASKDWORD, 0x81004800);
+
+       /*path a IQK setting*/
+       rtl_set_bbreg(hw, RTx_IQK_Tone_A, MASKDWORD, 0x10008c1c);
+       rtl_set_bbreg(hw, RRx_IQK_Tone_A, MASKDWORD, 0x30008c1c);
+       rtl_set_bbreg(hw, RTx_IQK_PI_A, MASKDWORD, 0x82160804);
+       rtl_set_bbreg(hw, RRx_IQK_PI_A, MASKDWORD, 0x28160000);
+
+       /*LO calibration Setting*/
+       rtl_set_bbreg(hw, RIQK_AGC_Rsp, MASKDWORD, 0x0046a911);
+       /*one shot,path A LOK & iqk*/
+       rtl_set_bbreg(hw, RIQK_AGC_Pts, MASKDWORD, 0xf9000000);
+       rtl_set_bbreg(hw, RIQK_AGC_Pts, MASKDWORD, 0xf8000000);
+
+       mdelay(IQK_DELAY_TIME);
+
+       reg_eac = rtl_get_bbreg(hw, RRx_Power_After_IQK_A_2, MASKDWORD);
+       reg_e94 = rtl_get_bbreg(hw, RTx_Power_Before_IQK_A, MASKDWORD);
+       reg_e9c = rtl_get_bbreg(hw, RTx_Power_After_IQK_A, MASKDWORD);
+
+
+       if (!(reg_eac & BIT(28)) &&
+           (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
+           (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
+               result |= 0x01;
+       else
+               return result;
+
+       u32temp = 0x80007C00 | (reg_e94&0x3FF0000)  | ((reg_e9c&0x3FF0000) >> 16);
+       rtl_set_bbreg(hw, RTx_IQK, MASKDWORD, u32temp);
+       /*RX IQK*/
+       /*Modify RX IQK mode table*/
+       rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
+       rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
+       rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
+       rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
+       rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
+       rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
+
+       /*IQK Setting*/
+       rtl_set_bbreg(hw, RRx_IQK, MASKDWORD, 0x01004800);
+
+       /*path a IQK setting*/
+       rtl_set_bbreg(hw, RTx_IQK_Tone_A, MASKDWORD, 0x30008c1c);
+       rtl_set_bbreg(hw, RRx_IQK_Tone_A, MASKDWORD, 0x10008c1c);
+       rtl_set_bbreg(hw, RTx_IQK_PI_A, MASKDWORD, 0x82160c05);
+       rtl_set_bbreg(hw, RRx_IQK_PI_A, MASKDWORD, 0x28160c05);
+
+       /*LO calibration Setting*/
+       rtl_set_bbreg(hw, RIQK_AGC_Rsp, MASKDWORD, 0x0046a911);
+       /*one shot,path A LOK & iqk*/
+       rtl_set_bbreg(hw, RIQK_AGC_Pts, MASKDWORD, 0xf9000000);
+       rtl_set_bbreg(hw, RIQK_AGC_Pts, MASKDWORD, 0xf8000000);
+
+       mdelay(IQK_DELAY_TIME);
+
+       reg_eac = rtl_get_bbreg(hw, RRx_Power_After_IQK_A_2, MASKDWORD);
+       reg_e94 = rtl_get_bbreg(hw, RTx_Power_Before_IQK_A, MASKDWORD);
+       reg_e9c = rtl_get_bbreg(hw, RTx_Power_After_IQK_A, MASKDWORD);
+       reg_ea4 = rtl_get_bbreg(hw, RRx_Power_Before_IQK_A_2, MASKDWORD);
+
+       if (!(reg_eac & BIT(27)) &&
+           (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
+           (((reg_eac & 0x03FF0000) >> 16) != 0x36))
+               result |= 0x02;
+       return result;
+}
+#endif
+
+u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
+{
+       u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] =
+               {1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,38,40,42,\
+               44,46,48,50,52,54,56,58,60,62,64,100,\
+               102,104,106,108,110,112,114,116,118,\
+               120,122,124,126,128,130,132,134,136,\
+               138,140,149,151,153,155,157,159,161,\
+               163,165};
+       u8 place = chnl;
+
+       if(chnl > 14)
+       {
+               for(place = 14; place<sizeof(channel_all); place++)
+               {
+                       if(channel_all[place] == chnl)
+                       {
+                               return place-13;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+void _rtl8812ae_iqk_rx_fill_iqc(
+       struct ieee80211_hw *hw,
+       enum radio_path path,
+       u32 rx_x,
+       u32 rx_y
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       switch (path) {
+       case RF90_PATH_A:
+               {
+                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+                       if (rx_x >> 1 ==0x112 || rx_y >> 1 == 0x3ee){
+                               rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x100);
+                               rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0);
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("RX_X = %x;;RX_Y = %x ====>fill to IQC\n",
+                                       rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff));
+                       }
+                       else{
+                               rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x >> 1);
+                               rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y >> 1);
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("RX_X = %x;;RX_Y = %x ====>fill to IQC\n",
+                                       rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff));
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("0xc10 = %x ====>fill to IQC\n",
+                                       rtl_read_dword(rtlpriv, 0xc10)));
+                       }
+               }
+               break;
+       case RF90_PATH_B:
+               {
+                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+                       if (rx_x >> 1 ==0x112 || rx_y >> 1 == 0x3ee){
+                               rtl_set_bbreg(hw, 0xe10, 0x000003ff, 0x100);
+                               rtl_set_bbreg(hw, 0xe10, 0x03ff0000, 0);
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("RX_X = %x;;RX_Y = %x ====>fill to IQC\n",
+                                       rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff));
+                       }
+                       else{
+                               rtl_set_bbreg(hw, 0xe10, 0x000003ff, rx_x >> 1);
+                               rtl_set_bbreg(hw, 0xe10, 0x03ff0000, rx_y >> 1);
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("RX_X = %x;;RX_Y = %x====>fill to IQC\n ",
+                                       rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff));
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("0xe10 = %x====>fill to IQC\n",
+                                       rtl_read_dword(rtlpriv, 0xe10)));
+                       }
+               }
+               break;
+       default:
+               break;
+       };
+}
+
+void _rtl8812ae_iqk_tx_fill_iqc(
+       struct ieee80211_hw *hw,
+       enum radio_path path,
+       u32 tx_x,
+       u32 tx_y
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       switch (path) {
+       case RF90_PATH_A:
+               {
+                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /*[31] = 1 --> Page C1*/
+                       rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
+                       rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
+                       rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
+                       rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
+                       rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
+                               tx_x & 0x000007ff, tx_y & 0x000007ff));
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
+                               rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
+                               rtl_get_bbreg(hw, 0xccc, 0x000007ff)));
+               }
+               break;
+       case RF90_PATH_B:
+               {
+                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /*[31] = 1 --> Page C1*/
+                       rtl_write_dword(rtlpriv, 0xe90, 0x00000080);
+                       rtl_write_dword(rtlpriv, 0xec4, 0x20040000);
+                       rtl_write_dword(rtlpriv, 0xec8, 0x20000000);
+                       rtl_set_bbreg(hw, 0xecc, 0x000007ff, tx_y);
+                       rtl_set_bbreg(hw, 0xed4, 0x000007ff, tx_x);
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
+                               tx_x&0x000007ff, tx_y&0x000007ff));
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("0xed4 = %x;;0xecc = %x ====>fill to IQC\n",
+                               rtl_get_bbreg(hw, 0xed4, 0x000007ff),
+                               rtl_get_bbreg(hw, 0xecc, 0x000007ff)));
+               }
+               break;
+       default:
+               break;
+       };
+}
+
+void _rtl8812ae_iqk_backup_macbb(
+       struct ieee80211_hw *hw,
+       u32 *macbb_backup,
+       u32 *backup_macbb_reg,
+       u32 mac_bb_num
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+        /*save MACBB default value*/
+       for (i = 0; i < mac_bb_num; i++) {
+               macbb_backup[i] =rtl_read_dword(rtlpriv,backup_macbb_reg[i]);
+       }
+
+       RT_TRACE(COMP_IQK, DBG_LOUD, ("BackupMacBB Success!!!!\n"));
+}
+
+void _rtl8812ae_iqk_backup_afe(
+       struct ieee80211_hw *hw,
+       u32 *afe_backup,
+       u32 *backup_afe_REG,
+       u32 afe_num
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       /*Save AFE Parameters */
+       for (i = 0; i < afe_num; i++){
+               afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
+       }
+       RT_TRACE(COMP_IQK, DBG_LOUD, ("BackupAFE Success!!!!\n"));
+}
+
+void _rtl8812ae_iqk_backup_rf(
+       struct ieee80211_hw *hw,
+       u32 *rfa_backup,
+       u32 *rfb_backup,
+       u32 *backup_rf_reg,
+       u32 rf_num
+       )
+{
+
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       /*Save RF Parameters*/
+       for (i = 0; i < rf_num; i++){
+               rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i], BMASKDWORD);
+               rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i], BMASKDWORD);
+       }
+       RT_TRACE(COMP_IQK, DBG_LOUD, ("BackupRF Success!!!!\n"));
+}
+
+void _rtl8812ae_iqk_configure_mac(
+       struct ieee80211_hw *hw
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       /* ========MAC register setting========*/
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       rtl_write_byte(rtlpriv, 0x522, 0x3f);
+       rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
+       rtl_write_byte(rtlpriv, 0x808, 0x00);           /*RX ante off*/
+       rtl_set_bbreg(hw, 0x838, 0xf, 0xc);             /*CCA off*/
+}
+
+#define cal_num 10
+
+void _rtl8812ae_iqk_tx(
+       struct ieee80211_hw *hw,
+       u8 chnl_idx
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       u8 delay_count;
+       u8 cal0_retry, cal1_retry;
+       u8 tx0_average = 0, tx1_average = 0, rx0_average = 0, rx1_average = 0;
+       int tx0_x = 0, tx0_y = 0, rx0_x = 0, rx0_y = 0;
+       int tx_x0[cal_num], tx_y0[cal_num], rx_x0[cal_num], rx_y0[cal_num];
+       int tx1_x = 0, tx1_y = 0, rx1_x = 0, rx1_y = 0;
+       int tx_x1[cal_num], tx_y1[cal_num], rx_x1[cal_num], rx_y1[cal_num];
+       bool tx0iqkok= false, rx0iqkok = false, tx0_fail = true, rx0_fail;
+       bool iqk0_ready = false, tx0_finish = false, rx0_finish = false;
+       bool tx1iqkok = false, rx1iqkok = false, tx1_fail = true, rx1_fail;
+       bool iqk1_ready = false, tx1_finish = false, rx1_finish = false, vdf_enable = false;
+       int i, tx_dt[3], rx_dt[3], ii, dx = 0, dy = 0;
+
+       RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("BandWidth = %d.\n",
+                       rtlphy->current_chan_bw));
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80){
+               vdf_enable = true;
+       }
+       vdf_enable = false;
+
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       /*========Path-A AFE all on========*/
+       /*Port 0 DAC/ADC on*/
+       rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
+       rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
+
+       /* Port 1 DAC/ADC off*/
+       rtl_write_dword(rtlpriv, 0xe60, 0x77777777);
+       rtl_write_dword(rtlpriv, 0xe64, 0x77777777);
+
+       rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
+       rtl_write_dword(rtlpriv, 0xe68, 0x19791979);
+       rtl_set_bbreg(hw,0xc00, 0xf, 0x4);/*hardware 3-wire off*/
+       rtl_set_bbreg(hw,0xe00, 0xf, 0x4);/*hardware 3-wire off*/
+
+       /*DAC/ADC sampling rate (160 MHz)*/
+       rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
+       rtl_set_bbreg(hw, 0xe5c, BIT(26) | BIT(25) | BIT(24), 0x7);
+       rtl_set_bbreg(hw, 0x8c4, BIT(30), 0x1);
+
+        /*====== Path A TX IQK RF Setting ======*/
+       rtl_set_bbreg(hw,0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+       rtl_set_rfreg(hw,RF90_PATH_A, 0xef, BRFREGOFFSETMASK, 0x80002);
+       rtl_set_rfreg(hw,RF90_PATH_A, 0x30, BRFREGOFFSETMASK, 0x20000);
+       rtl_set_rfreg(hw,RF90_PATH_A, 0x31, BRFREGOFFSETMASK, 0x3fffd);
+       rtl_set_rfreg(hw,RF90_PATH_A, 0x32, BRFREGOFFSETMASK, 0xfe83f);
+       rtl_set_rfreg(hw,RF90_PATH_A, 0x65, BRFREGOFFSETMASK, 0x931d5);
+       rtl_set_rfreg(hw,RF90_PATH_A, 0x8f, BRFREGOFFSETMASK, 0x8a001);
+       /*====== Path A TX IQK RF Setting ======*/
+       rtl_set_rfreg(hw,RF90_PATH_B, 0xef, BRFREGOFFSETMASK, 0x80002);
+       rtl_set_rfreg(hw,RF90_PATH_B, 0x30, BRFREGOFFSETMASK, 0x20000);
+       rtl_set_rfreg(hw,RF90_PATH_B, 0x31, BRFREGOFFSETMASK, 0x3fffd);
+       rtl_set_rfreg(hw,RF90_PATH_B, 0x32, BRFREGOFFSETMASK, 0xfe83f);
+       rtl_set_rfreg(hw,RF90_PATH_B, 0x65, BRFREGOFFSETMASK, 0x931d5);
+       rtl_set_rfreg(hw,RF90_PATH_B, 0x8f, BRFREGOFFSETMASK, 0x8a001);
+       rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
+       rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
+       rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
+       rtl_set_bbreg(hw, 0xe94, BIT(0), 0x1);
+       rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y)*/
+       rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y)*/
+       rtl_write_dword(rtlpriv, 0x984, 0x00462910);/*[0]:AGC_en, [15]:idac_K_Mask*/
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1*/
+
+       /*ExternalPA_5G == 0*/
+       rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
+       rtl_write_dword(rtlpriv, 0xe88, 0x821403f1);
+
+       if (rtlhal->current_bandtype){
+               rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
+               rtl_write_dword(rtlpriv, 0xe8c, 0x68163e96);
+       }
+       else{
+               rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
+               rtl_write_dword(rtlpriv, 0xe8c, 0x28163e96);
+       }
+
+       if (vdf_enable){}
+       else{
+               rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/*TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16*/
+               rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/*RX_Tone_idx[9:0], RxK_Mask[29]*/
+               rtl_write_dword(rtlpriv, 0xce8, 0x00000000);
+               rtl_write_dword(rtlpriv, 0xe80, 0x18008c10);/*TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16*/
+               rtl_write_dword(rtlpriv, 0xe84, 0x38008c10);/*RX_Tone_idx[9:0], RxK_Mask[29]*/
+               rtl_write_dword(rtlpriv, 0xee8, 0x00000000);
+
+               cal0_retry = 0;
+               cal1_retry = 0;
+               while(1){
+                       /*one shot*/
+                       rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module*/
+                       rtl_write_dword(rtlpriv, 0xeb8, 0x00100000);/* cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module*/
+                       rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
+                       rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
+
+                       mdelay(10); /*Delay 25ms*/
+                       rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+                       rtl_write_dword(rtlpriv, 0xeb8, 0x00000000);
+                       delay_count = 0;
+                       while (1){
+                               if (!tx0_finish)
+                                       iqk0_ready = (bool) rtl_get_bbreg(hw, 0xd00, BIT(10));
+                               if (!tx1_finish)
+                                       iqk1_ready = (bool) rtl_get_bbreg(hw, 0xd40, BIT(10));
+                               if ((iqk0_ready && iqk1_ready) || (delay_count>20))
+                                       break;
+                               else{
+                               mdelay(1);
+                               delay_count++;
+                               }
+                       }
+                       RT_TRACE(COMP_IQK, DBG_LOUD, ("TX delay_count = %d\n", delay_count));
+                       if (delay_count < 20){                                                  // If 20ms No Result, then cal_retry++
+                               /* ============TXIQK Check==============*/
+                               tx0_fail = (bool) rtl_get_bbreg(hw, 0xd00, BIT(12));
+                               tx1_fail = (bool) rtl_get_bbreg(hw, 0xd40, BIT(12));
+                               if (!(tx0_fail || tx0_finish)){
+                                       rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
+                                       tx_x0[tx0_average] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000) << 21;
+                                       rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
+                                       tx_y0[tx0_average] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000) << 21;
+                                       tx0iqkok = true;
+                                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                                               ("TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n",
+                                               tx0_average, (tx_x0[tx0_average]) >> 21 & 0x000007ff,
+                                               tx0_average, (tx_y0[tx0_average]) >> 21 & 0x000007ff));
+
+                                       tx0_average++;
+                       }
+                       else{
+                               tx0iqkok = false;
+                               cal0_retry++;
+                               if (cal0_retry == 10)
+                                       break;
+                               }
+                       if (!(tx1_fail || tx1_finish)){
+                               rtl_write_dword(rtlpriv, 0xeb8, 0x02000000);
+                               tx_x1[tx1_average] = rtl_get_bbreg(hw, 0xd40, 0x07ff0000) << 21;
+                               rtl_write_dword(rtlpriv, 0xeb8, 0x04000000);
+                               tx_y1[tx1_average] = rtl_get_bbreg(hw, 0xd40, 0x07ff0000) << 21;
+                               tx1iqkok= true;
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("TX_X1[%d] = %x ;; TX_Y1[%d] = %x\n",
+                                       tx1_average, (tx_x1[tx1_average]) >> 21 & 0x000007ff,
+                                       tx1_average, (tx_y1[tx1_average]) >> 21 & 0x000007ff));
+
+                               tx1_average++;
+                               }
+                       else{
+                               tx1iqkok = false;
+                               cal1_retry++;
+                               if (cal1_retry == 10)
+                                       break;
+                               }
+                       }
+                       else{
+                               tx0iqkok = false;
+                               tx1iqkok = false;
+                               cal0_retry++;
+                               cal1_retry++;
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("Delay 20ms TX IQK Not Ready!!!!!\n"));
+                               if (cal0_retry == 10)
+                                       break;
+                       }
+                       if (tx0_average >= 2){
+                               for (i = 0; i < tx0_average; i++){
+                                       for (ii = i+1; ii <tx0_average; ii++){
+                                               dx = (tx_x0[i] >> 21) - (tx_x0[ii] >> 21);
+                                               if (dx < 4 && dx > -4){
+                                                       dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
+                                                       if (dy < 4 && dy > -4){
+                                                               tx0_x = ((tx_x0[i] >> 21) + (tx_x0[ii] >> 21)) / 2;
+                                                               tx0_y = ((tx_y0[i] >> 21) + (tx_y0[ii] >> 21)) / 2;
+                                                               tx_x0[0] = tx_x0[i];
+                                                               tx_y0[1] = tx_y0[ii];
+                                                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                                                       ("TX0_X = %x;;TX0_Y = %x\n",
+                                                                       tx0_x & 0x000007ff, tx0_y & 0x000007ff));
+                                                               if ((rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
+                                                                       && vdf_enable) {
+                                                                       tx_dt[0] = (tx_dt[i] + tx_dt[ii]) / 2;
+                                                               }
+                                                               tx0_finish = true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       if (tx1_average >= 2){
+                               for (i = 0; i < tx1_average; i++){
+                                       for (ii = i+1; ii < tx1_average; ii++){
+                                               dx = (tx_x1[i] >> 21) - (tx_x1[ii] >> 21);
+                                               if (dx < 4 && dx > -4){
+                                                       dy = (tx_y1[i] >> 21) - (tx_y1[ii] >> 21);
+                                                       if (dy < 4 && dy > -4){
+                                                               tx1_x = ((tx_x1[i] >> 21) + (tx_x1[ii] >> 21)) / 2;
+                                                               tx1_y = ((tx_y1[i] >> 21) + (tx_y1[ii] >> 21)) / 2;
+                                                               tx_x1[0] = tx_x1[i];
+                                                               tx_y1[1] = tx_y1[ii];
+                                                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                                                       ("TX1_X = %x;;TX1_Y = %x\n",
+                                                                       tx1_x & 0x000007ff, tx1_y & 0x000007ff));
+                                                               if ((rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
+                                                                       && vdf_enable) {
+                                                                       tx_dt[0] = (tx_dt[i] +  tx_dt[ii]) / 2;
+                                                               }
+                                                               tx1_finish = true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("TX0_Average = %d, TX1_Average = %d\n",
+                               tx0_average, tx1_average));
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("TX0_finish = %d, TX1_finish = %d\n",
+                               tx0_finish, tx1_finish));
+                       if (tx0_finish && tx1_finish)
+                               break;
+                       if ((cal0_retry + tx0_average) >= 10
+                               || (cal1_retry + tx1_average) >= 10 )
+                               break;
+               }
+               RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("TXA_cal_retry = %d\n", cal0_retry));
+               RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("TXB_cal_retry = %d\n", cal1_retry));
+
+       }
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C*/
+       rtl_set_rfreg(hw, RF90_PATH_A, 0x58, 0x7fe00,
+               rtl_get_rfreg(hw, RF90_PATH_A, 0x8, 0xffc00)); /*Load LOK*/
+       rtl_set_rfreg(hw, RF90_PATH_B, 0x58, 0x7fe00,
+               rtl_get_rfreg(hw, RF90_PATH_B, 0x8, 0xffc00)); /* Load LOK*/
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /*[31] = 1 --> Page C1*/
+
+
+       if (vdf_enable) {}
+       else{
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+               if (tx0_finish) {
+                       /*====== Path A RX IQK RF Setting======*/
+                       rtl_set_rfreg(hw, RF90_PATH_A, 0xef, BRFREGOFFSETMASK, 0x80000);
+                       rtl_set_rfreg(hw, RF90_PATH_A, 0x18, 0x00c00, 0x3);     /* BW 20M*/
+                       rtl_set_rfreg(hw, RF90_PATH_A, 0x30, BRFREGOFFSETMASK, 0x30000);
+                       rtl_set_rfreg(hw, RF90_PATH_A, 0x31, BRFREGOFFSETMASK, 0x3f7ff);
+                       rtl_set_rfreg(hw, RF90_PATH_A, 0x32, BRFREGOFFSETMASK, 0xfe7bf);
+                       rtl_set_rfreg(hw, RF90_PATH_A, 0x8f, BRFREGOFFSETMASK, 0x88001);
+                       rtl_set_rfreg(hw, RF90_PATH_A, 0x65, BRFREGOFFSETMASK, 0x931d6);
+                       rtl_set_rfreg(hw, RF90_PATH_A, 0xef, BRFREGOFFSETMASK, 0x00000);
+               }
+               if (tx1_finish){
+                       /*====== Path B RX IQK RF Setting======*/
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0xef, BRFREGOFFSETMASK, 0x80000);
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0x30, BRFREGOFFSETMASK, 0x30000);
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0x31, BRFREGOFFSETMASK, 0x3f7ff);
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0x32, BRFREGOFFSETMASK, 0xfe7bf);
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0x8f, BRFREGOFFSETMASK, 0x88001);
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0x65, BRFREGOFFSETMASK, 0x931d1);
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0xef, BRFREGOFFSETMASK, 0x00000);
+               }
+               rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
+               rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
+               rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
+               rtl_write_dword(rtlpriv, 0x984, 0x0046a890);
+
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /*[31] = 1 --> Page C1*/
+               if (tx0_finish) {
+                       rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/*TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16*/
+                       rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/*RX_Tone_idx[9:0], RxK_Mask[29]*/
+                       rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
+                       rtl_write_dword(rtlpriv, 0xc8c, 0x28160cc0);
+               }
+               if (tx1_finish){
+                       rtl_write_dword(rtlpriv, 0xe80, 0x38008c10);/*TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16*/
+                       rtl_write_dword(rtlpriv, 0xe84, 0x18008c10);/*RX_Tone_idx[9:0], RxK_Mask[29]*/
+                       rtl_write_dword(rtlpriv, 0xe88, 0x02140119);
+                       rtl_write_dword(rtlpriv, 0xe8c, 0x28160ca0);
+               }
+              cal0_retry = 0;
+               cal1_retry = 0;
+               while(1){
+                   /* one shot*/
+                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+                       if (tx0_finish){
+                               rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0[rx0_average % 2]) >> 21 & 0x000007ff);
+                               rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0[rx0_average % 2]) >> 21 & 0x000007ff);
+                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1*/
+                               rtl_write_dword(rtlpriv, 0xcb8, 0x00300000);/*cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module*/
+                               rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);
+                               mdelay(5); /*Delay 10ms*/
+                       }
+                       if (tx1_finish){
+                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+                               rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x1[rx1_average % 2]) >> 21 & 0x000007ff);
+                               rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y1[rx1_average % 2]) >> 21 & 0x000007ff);
+                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /*[31] = 1 --> Page C1*/
+                               rtl_write_dword(rtlpriv, 0xeb8, 0x00300000);/*cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module*/
+                               rtl_write_dword(rtlpriv, 0xeb8, 0x00100000);/* cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module*/
+                       }
+                       mdelay(10); /*Delay 10ms*/
+                       rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+                       rtl_write_dword(rtlpriv, 0xeb8, 0x00000000);
+                       delay_count = 0;
+                       while (1){
+                               if (!rx0_finish && tx0_finish)
+                                       iqk0_ready = (bool) rtl_get_bbreg(hw, 0xd00, BIT(10));
+                               if (!rx1_finish && tx1_finish)
+                                       iqk1_ready = (bool) rtl_get_bbreg(hw, 0xd40, BIT(10));
+                               if ((iqk0_ready && iqk1_ready)||(delay_count>20))
+                                       break;
+                               else{
+                                       mdelay(1);
+                                       delay_count++;
+                               }
+                       }
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("RX delay_count = %d\n", delay_count));
+                       if (delay_count < 20){  // If 20ms No Result, then cal_retry++
+                               // ============RXIQK Check==============
+                               rx0_fail = (bool) rtl_get_bbreg(hw, 0xd00, BIT(11));
+                               rx1_fail = (bool) rtl_get_bbreg(hw, 0xd40, BIT(11));
+                               if (!(rx0_fail || rx0_finish) && tx0_finish){
+                                       rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
+                                       rx_x0[rx0_average] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000) << 21;
+                                       rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
+                                       rx_y0[rx0_average] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000) << 21;
+                                       rx0iqkok= true;
+                                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                                               ("RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n",
+                                               rx0_average, (rx_x0[rx0_average]) >> 21 & 0x000007ff,
+                                               rx0_average, (rx_y0[rx0_average]) >> 21 & 0x000007ff));
+
+                                       rx0_average++;
+                               }
+                               else{
+                                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                                               ("1. RXA_cal_retry = %d\n", cal0_retry));
+                                       rx0iqkok = false;
+                                       cal0_retry++;
+                                       if (cal0_retry == 10)
+                                       break;
+                               }
+                               if (!(rx1_fail || rx1_finish) && tx1_finish){
+                                       rtl_write_dword(rtlpriv, 0xeb8, 0x06000000);
+                                       rx_x1[rx1_average] = rtl_get_bbreg(hw, 0xd40, 0x07ff0000) << 21;
+                                       rtl_write_dword(rtlpriv, 0xeb8, 0x08000000);
+                                       rx_y1[rx1_average] = rtl_get_bbreg(hw, 0xd40, 0x07ff0000) << 21;
+                                       rx1iqkok = true;
+                                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                                               ("RX_X1[%d] = %x ;; RX_Y1[%d] = %x\n",
+                                               rx1_average, (rx_x1[rx1_average]) >> 21 & 0x000007ff,
+                                               rx1_average, (rx_y1[rx1_average]) >> 21 & 0x000007ff));
+
+                                       rx1_average++;
+                               }
+                               else{
+                                       rx1iqkok= false;
+                                       cal1_retry++;
+                                       if (cal1_retry == 10)
+                                               break;
+                               }
+
+                       }
+                       else{
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("2. RXA_cal_retry = %d\n", cal0_retry));
+                               rx0iqkok = false;
+                               rx1iqkok = false;
+                               cal0_retry++;
+                               cal1_retry++;
+                               RT_TRACE(COMP_IQK, DBG_LOUD,
+                                       ("Delay 20ms RX IQK Not Ready!!!!!\n"));
+                           if (cal0_retry == 10)
+                               break;
+                       }
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("3. RXA_cal_retry = %d\n", cal0_retry));
+                       if (rx0_average >= 2){
+                               for (i = 0; i < rx0_average; i++){
+                                       for (ii = i+1; ii < rx0_average; ii++){
+                                       dx = (rx_x0[i] >> 21) - (rx_x0[ii] >> 21);
+                                               if (dx < 4 && dx > -4){
+                                               dy = (rx_y0[i] >> 21) - (rx_y0[ii] >> 21);
+                                                       if (dy < 4 && dy > -4){
+                                                               rx0_x = ((rx_x0[i]>>21) + (rx_x0[ii] >> 21)) / 2;
+                                                               rx0_y = ((rx_y0[i]>>21) + (rx_y0[ii] >> 21)) / 2;
+                                                               if ((rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
+                                                                       && vdf_enable) {
+                                                                       rx_dt[0] = (rx_dt[i] + rx_dt[ii]) / 2;
+                                                               }
+                                                               rx0_finish = true;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       if (rx1_average >= 2){
+                               for (i = 0; i < rx1_average; i++){
+                                       for (ii = i+1; ii < rx1_average; ii++){
+                                       dx = (rx_x1[i] >> 21) - (rx_x1[ii] >> 21);
+                                               if (dx < 4 && dx > -4){
+                                               dy = (rx_y1[i] >> 21) - (rx_y1[ii] >> 21);
+                                                       if (dy < 4 && dy > -4){
+                                                               rx1_x = ((rx_x1[i] >> 21) + (rx_x1[ii] >> 21)) / 2;
+                                                               rx1_y = ((rx_y1[i] >> 21) + (rx_y1[ii] >> 21)) / 2;
+                                                               if ((rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
+                                                                       && vdf_enable) {
+                                                                       rx_dt[0] = (rx_dt[i] + rx_dt[ii]) / 2;
+                                                               }
+                                                               rx1_finish = true;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("RX0_Average = %d, RX1_Average = %d\n",
+                               rx0_average, rx1_average));
+                       RT_TRACE(COMP_IQK, DBG_LOUD,
+                               ("RX0_finish = %d, RX1_finish = %d\n",
+                               rx0_finish, rx1_finish));
+                       if ((rx0_finish|| !tx0_finish) && (rx1_finish || !tx1_finish) )
+                               break;
+                       if ((cal0_retry + rx0_average) >= 10
+                               || (cal1_retry + rx1_average) >= 10
+                               || rx0_average == 3
+                               || rx1_average == 3)
+                               break;
+               }
+               RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("RXA_cal_retry = %d\n", cal0_retry));
+               RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("RXB_cal_retry = %d\n", cal1_retry));
+       }
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C*/
+       switch (rtlphy->current_chan_bw)
+       {
+       case HT_CHANNEL_WIDTH_20_40:
+               {
+               rtl_set_rfreg(hw, RF90_PATH_A, 0x18, 0x00c00, 0x1);
+               }
+               break;
+       case HT_CHANNEL_WIDTH_80:
+               {
+               rtl_set_rfreg(hw, RF90_PATH_A, 0x18, 0x00c00, 0x0);
+               }
+               break;
+       default:
+               break;
+
+       }
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 0 --> Page C*/
+       /*FillIQK Result*/
+       RT_TRACE(COMP_IQK, DBG_LOUD,
+               ("========Path_A =======\n"));
+
+       if (tx0_finish){
+               _rtl8812ae_iqk_tx_fill_iqc(hw, RF90_PATH_A, tx0_x, tx0_y);
+       }
+       else{
+               _rtl8812ae_iqk_tx_fill_iqc(hw, RF90_PATH_A, 0x200, 0x0);
+       }
+
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80
+               || vdf_enable){
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /*[31] = 0 --> Page C*/
+               rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[0] & 0x00003fff);
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       }
+
+       if (rx0_finish == 1){
+               _rtl8812ae_iqk_rx_fill_iqc(hw, RF90_PATH_A, rx0_x, rx0_y);
+       }
+       else{
+               _rtl8812ae_iqk_rx_fill_iqc(hw, RF90_PATH_A, 0x200, 0x0);
+       }
+
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80
+               || vdf_enable){
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /*[31] = 0 --> Page C*/
+               rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[0] & 0x00003fff);
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C*/
+       }
+
+       RT_TRACE(COMP_IQK, DBG_LOUD,
+               ("========Path_B =======\n"));
+
+       if (tx1_finish){
+               _rtl8812ae_iqk_tx_fill_iqc(hw, RF90_PATH_B, tx1_x, tx1_y);
+       }
+       else{
+               _rtl8812ae_iqk_tx_fill_iqc(hw, RF90_PATH_B, 0x200, 0x0);
+       }
+
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80
+               || vdf_enable){
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 0 --> Page C*/
+               rtl_set_bbreg(hw, 0xee8, 0x3fff0000, tx_dt[0] & 0x00003fff);
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C*/
+       }
+
+       if (rx1_finish == 1){
+               _rtl8812ae_iqk_rx_fill_iqc(hw, RF90_PATH_B, rx1_x, rx1_y);
+       }
+       else{
+               _rtl8812ae_iqk_rx_fill_iqc(hw, RF90_PATH_B, 0x200, 0x0);
+       }
+
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80
+               || vdf_enable){
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 0 --> Page C*/
+               rtl_set_bbreg(hw, 0xee8, 0x00003fff, rx_dt[0] & 0x00003fff);
+               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C*/
+       }
+}
+
+void _rtl8812ae_iqk_restore_rf(
+       struct ieee80211_hw *hw,
+       enum radio_path path,
+       u32 *backup_rf_reg,
+       u32 *rf_backup,
+       u32 rf_reg_num
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       for (i = 0; i < rf_reg_num; i++)
+               rtl_set_rfreg(hw, path, backup_rf_reg[i], BRFREGOFFSETMASK, rf_backup[i]);
+
+       rtl_set_rfreg(hw, path, 0xef, BRFREGOFFSETMASK, 0x0);
+
+       switch(path){
+       case RF90_PATH_A:
+       {
+               RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("RestoreRF Path A Success!!!!\n"));
+       }
+               break;
+       case RF90_PATH_B:
+       {
+               RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("RestoreRF Path B Success!!!!\n"));
+       }
+               break;
+       default:
+               break;
+       }
+}
+
+void _rtl8812ae_iqk_restore_afe(
+       struct ieee80211_hw *hw,
+       u32 *afe_backup,
+       u32 *backup_afe_reg,
+       u32 afe_num
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       /*Reload AFE Parameters */
+       for (i = 0; i < afe_num; i++){
+               rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
+       }
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1*/
+       rtl_write_dword(rtlpriv, 0xc80, 0x0);
+       rtl_write_dword(rtlpriv, 0xc84, 0x0);
+       rtl_write_dword(rtlpriv, 0xc88, 0x0);
+       rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
+       rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
+       rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
+       rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
+       rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
+       rtl_write_dword(rtlpriv, 0xcb8, 0x0);
+       rtl_write_dword(rtlpriv, 0xe80, 0x0);
+       rtl_write_dword(rtlpriv, 0xe84, 0x0);
+       rtl_write_dword(rtlpriv, 0xe88, 0x0);
+       rtl_write_dword(rtlpriv, 0xe8c, 0x3c000000);
+       rtl_write_dword(rtlpriv, 0xe90, 0x00000080);
+       rtl_write_dword(rtlpriv, 0xe94, 0x00000000);
+       rtl_write_dword(rtlpriv, 0xec4, 0x20040000);
+       rtl_write_dword(rtlpriv, 0xec8, 0x20000000);
+       rtl_write_dword(rtlpriv, 0xeb8, 0x0);
+       RT_TRACE(COMP_IQK, DBG_LOUD,
+               ("RestoreAFE Success!!!!\n"));
+}
+
+void _rtl8812ae_iqk_restore_macbb(
+       struct ieee80211_hw *hw,
+       u32 *macbb_backup,
+       u32 *backup_macbb_reg,
+       u32 macbb_num
+       )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C*/
+       //Reload MacBB Parameters
+       for (i = 0; i < macbb_num; i++){
+               rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
+       }
+       RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("RestoreMacBB Success!!!!\n"));
+}
+
+#define MACBB_REG_NUM 10
+#define AFE_REG_NUM 14
+#define RF_REG_NUM 3
+
+static void _rtl8812ae_phy_iq_calibrate(
+               struct ieee80211_hw *hw,
+               u8 channel)
+{
+       u32     macbb_backup[MACBB_REG_NUM];
+       u32 afe_backup[AFE_REG_NUM];
+       u32 rfa_backup[RF_REG_NUM];
+       u32 rfb_backup[RF_REG_NUM];
+       u32     backup_macbb_reg[MACBB_REG_NUM] = {0xb00, 0x520, 0x550,
+                                                                                       0x808, 0x90c, 0xc00, 0xe00,
+                                                                                       0x8c4,0x838,  0x82c};
+       u32     backup_afe_reg[AFE_REG_NUM] = {0xc5c, 0xc60, 0xc64, 0xc68,
+                                                                               0xcb8, 0xcb0, 0xcb4,0xe5c,
+                                                                               0xe60, 0xe64, 0xe68, 0xeb8,
+                                                                               0xeb0, 0xeb4};
+       u32     backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
+       u8      chnl_idx = _rtl8812ae_get_right_chnl_place_for_iqk(channel);
+
+       _rtl8812ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg, MACBB_REG_NUM);
+       _rtl8812ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
+       _rtl8812ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg, RF_REG_NUM);
+
+       _rtl8812ae_iqk_configure_mac(hw);
+       _rtl8812ae_iqk_tx(hw, chnl_idx);
+       _rtl8812ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup, RF_REG_NUM);
+       _rtl8812ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfb_backup, RF_REG_NUM); // PATH_A ?
+
+       _rtl8812ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
+       _rtl8812ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg, MACBB_REG_NUM);
+}
+
+
+void _rtl8821ae_iqk_backup_macbb(
+               struct ieee80211_hw *hw,
+               u32 *macbb_backup,
+               u32 *backup_macbb_reg,
+               u32 mac_bb_num
+               )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       /*save MACBB default value*/
+       for (i = 0; i < mac_bb_num; i++) {
+               macbb_backup[i] =rtl_read_dword(rtlpriv,backup_macbb_reg[i]);
+       }
+
+       RT_TRACE(COMP_IQK, DBG_LOUD, ("BackupMacBB Success!!!!\n"));
+}
+
+void _rtl8821ae_iqk_backup_afe(
+               struct ieee80211_hw *hw,
+               u32 *afe_backup,
+               u32 *backup_afe_REG,
+               u32 afe_num
+               )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       /*Save AFE Parameters */
+       for (i = 0; i < afe_num; i++){
+               afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
+       }
+       RT_TRACE(COMP_IQK, DBG_LOUD, ("BackupAFE Success!!!!\n"));
+}
+
+void _rtl8821ae_iqk_backup_rf(
+               struct ieee80211_hw *hw,
+               u32 *rfa_backup,
+               u32 *rfb_backup,
+               u32 *backup_rf_reg,
+               u32 rf_num
+               )
+{
+
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       /*Save RF Parameters*/
+       for (i = 0; i < rf_num; i++){
+               rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i], BMASKDWORD);
+               rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i], BMASKDWORD);
+       }
+       RT_TRACE(COMP_IQK, DBG_LOUD, ("BackupRF Success!!!!\n"));
+}
+
+void _rtl8821ae_iqk_configure_mac(
+               struct ieee80211_hw *hw
+               )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       /* ========MAC register setting========*/
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+       rtl_write_byte(rtlpriv, 0x522, 0x3f);
+       rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
+       rtl_write_byte(rtlpriv, 0x808, 0x00);           /*RX ante off*/
+       rtl_set_bbreg(hw, 0x838, 0xf, 0xc);             /*CCA off*/
+}
+
+
+void _rtl8821ae_iqk_tx_fill_iqc(
+               struct ieee80211_hw *hw,
+               enum radio_path path,
+               u32 tx_x,
+               u32 tx_y
+               )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       switch (path) {
+               case RF90_PATH_A:
+                       {
+                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+                               rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
+                               rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
+                               rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
+                               rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
+                               rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
+                               RT_TRACE(COMP_IQK, DBG_LOUD, ("TX_X = %x;;TX_Y = %x =====> fill to IQC\n", tx_x, tx_y));
+                               RT_TRACE(COMP_IQK, DBG_LOUD, ("0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", rtl_get_bbreg(hw, 0xcd4, 0x000007ff), rtl_get_bbreg(hw, 0xccc, 0x000007ff)));
+                       }
+                       break;
+               default:
+                       break;
+       };
+}
+
+
+void _rtl8821ae_iqk_rx_fill_iqc(
+               struct ieee80211_hw *hw,
+               enum radio_path path,
+               u32 rx_x,
+               u32 rx_y
+               )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       switch (path) {
+               case RF90_PATH_A:
+                       {
+                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+                               rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
+                               rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
+                               RT_TRACE(COMP_IQK, DBG_LOUD, ("rx_x = %x;;rx_y = %x ====>fill to IQC\n", rx_x>>1, rx_y>>1));
+                               RT_TRACE(COMP_IQK, DBG_LOUD, ("0xc10 = %x ====>fill to IQC\n", rtl_read_dword(rtlpriv, 0xc10)));
+                       }
+                       break;
+               default:
+                       break;
+       };
+}
+
+
+
+#define cal_num 10
+
+void _rtl8821ae_iqk_tx(
+               struct ieee80211_hw *hw,
+               enum radio_path path
+               )
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       u32     tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
+       int     tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
+       int     tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num], tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
+       bool    tx0iqkok = false, rx0iqkok = false;
+       bool    vdf_enable = false;
+       int     i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3], ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
+
+
+       RT_TRACE(COMP_IQK, DBG_LOUD,
+                       ("BandWidth = %d.\n",
+                        rtlphy->current_chan_bw));
+       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80){
+               vdf_enable = true;
+       }
+
+       while (cal < cal_num) {
+               switch (path) {
+                       case RF90_PATH_A:
+                               {
+                                       temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
+                                       //Path-A LOK
+                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
+                                       /*========Path-A AFE all on========*/
+                                       /*Port 0 DAC/ADC on*/
+                                       rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
+                                       rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
+                                       rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
+                                       rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
+                                       rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
+                                       rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
+                                       rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
+                                       rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
+                                       rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
+                                       rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
+
+                                       rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
+
+                                       // LOK Setting
+                                       //====== LOK ======
+                                       /*DAC/ADC sampling rate (160 MHz)*/
+                                       rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
+
+                                       // 2. LoK RF Setting (at BW = 20M)
+                                       rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
+                                       rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3);     // BW 20M
+                                       rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
+                                       rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
+                                       rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
+                                       rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
+                                       rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
+                                       rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
+                                       rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
+                                       rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
+                                       rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
+                                       rtl_write_dword(rtlpriv, 0x978, 0x29002000);// TX (X,Y)
+                                       rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);// RX (X,Y)
+                                       rtl_write_dword(rtlpriv, 0x984, 0x00462910);// [0]:AGC_en, [15]:idac_K_Mask
+
+                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+                                       rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
+
+                                       if (rtlhal->current_bandtype)
+                                               rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
+                                       else
+                                               rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
+
+                                       rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                       rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                       rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);// cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module
+                                       rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
+                                       rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
+
+                                       mdelay(10); //Delay 10ms
+                                       rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+
+                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+                                       rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); // Load LOK
+
+                                       switch (rtlphy->current_chan_bw)
+                                       {
+                                               case 1:
+                                                       {
+                                                               rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
+                                                       }
+                                                       break;
+                                               case 2:
+                                                       {
+                                                               rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
+                                                       }
+                                                       break;
+                                               default:
+                                                       break;
+
+                                       }
+
+                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+
+                                       // 3. TX RF Setting
+                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+                                       rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
+                                       rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
+                                       rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
+                                       rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
+                                       rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
+                                       rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
+                                       rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
+                                       //ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd);
+                                       rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
+                                       rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
+                                       rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
+                                       rtl_write_dword(rtlpriv, 0x978, 0x29002000);// TX (X,Y)
+                                       rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);// RX (X,Y)
+                                       rtl_write_dword(rtlpriv, 0x984, 0x0046a910);// [0]:AGC_en, [15]:idac_K_Mask
+
+                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+                                       rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
+                                       if (rtlhal->current_bandtype)
+                                               rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
+                                       else
+                                               rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
+
+                                       if (vdf_enable == 1){
+                                               RT_TRACE(COMP_IQK, DBG_LOUD, ("VDF_enable\n"));
+                                               for (k = 0;k <= 2; k++){
+                                                       switch (k){
+                                                               case 0:
+                                                                       {
+                                                                               rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                                                               rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                                                               rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
+                                                                       }
+                                                                       break;
+                                                               case 1:
+                                                                       {
+                                                                               rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
+                                                                               rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
+                                                                               rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
+                                                                       }
+                                                                       break;
+                                                               case 2:
+                                                                       {
+                                                                               RT_TRACE(COMP_IQK, DBG_LOUD, ("vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff));
+                                                                               RT_TRACE(COMP_IQK, DBG_LOUD, ("vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff));
+                                                                               tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
+                                                                               tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
+                                                                               tx_dt[cal] = (tx_dt[cal] >> 1 )+(tx_dt[cal] & BIT(0));
+                                                                               rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                                                               rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                                                               rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
+                                                                               rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
+                                                                       }
+                                                                       break;
+                                                               default:
+                                                                       break;
+                                                       }
+                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);// cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module
+                                                       cal_retry = 0;
+                                                       while(1){
+                                                               // one shot
+                                                               rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
+                                                               rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
+
+                                                               mdelay(10); //Delay 10ms
+                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+                                                               delay_count = 0;
+                                                               while (1){
+                                                                       iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
+                                                                       if ((~iqk_ready) || (delay_count>20)){
+                                                                               break;
+                                                                       }
+                                                                       else{
+                                                                               mdelay(1);
+                                                                               delay_count++;
+                                                                       }
+                                                               }
+
+                                                               if (delay_count < 20){                                                  // If 20ms No Result, then cal_retry++
+                                                                       // ============TXIQK Check==============
+                                                                       tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
+
+                                                                       if (~tx_fail){
+                                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
+                                                                               vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
+                                                                               vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                               tx0iqkok = true;
+                                                                               break;
+                                                                       }
+                                                                       else{
+                                                                               rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
+                                                                               rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
+                                                                               tx0iqkok = false;
+                                                                               cal_retry++;
+                                                                               if (cal_retry == 10) {
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               else{
+                                                                       tx0iqkok = false;
+                                                                       cal_retry++;
+                                                                       if (cal_retry == 10){
+                                                                               break;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                               if (k == 3){
+                                                       tx_x0[cal] = vdf_x[k-1] ;
+                                                       tx_y0[cal] = vdf_y[k-1];
+                                               }
+                                       }
+
+                                       else {
+                                               rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                               rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                               rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);// cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module
+                                               cal_retry = 0;
+                                               while(1){
+                                                       // one shot
+                                                       rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
+                                                       rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
+
+                                                       mdelay(10); //Delay 10ms
+                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+                                                       delay_count = 0;
+                                                       while (1){
+                                                               iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
+                                                               if ((~iqk_ready) || (delay_count>20)) {
+                                                                       break;
+                                                               }
+                                                               else{
+                                                                       mdelay(1);
+                                                                       delay_count++;
+                                                               }
+                                                       }
+
+                                                       if (delay_count < 20){                                                  // If 20ms No Result, then cal_retry++
+                                                               // ============TXIQK Check==============
+                                                               tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
+
+                                                               if (~tx_fail){
+                                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
+                                                                       tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
+                                                                       tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                       tx0iqkok = true;
+                                                                       break;
+                                                               }
+                                                               else{
+                                                                       rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
+                                                                       rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
+                                                                       tx0iqkok = false;
+                                                                       cal_retry++;
+                                                                       if (cal_retry == 10) {
+                                                                               break;
+                                                                       }
+                                                               }
+                                                       }
+                                                       else{
+                                                               tx0iqkok = false;
+                                                               cal_retry++;
+                                                               if (cal_retry == 10)
+                                                                       break;
+                                                       }
+                                               }
+                                       }
+
+
+                                       if (tx0iqkok == false)
+                                               break;                          // TXK fail, Don't do RXK
+
+                                       if (vdf_enable == 1){
+                                               rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);    // TX VDF Disable
+                                               RT_TRACE(COMP_IQK, DBG_LOUD, ("RXVDF Start\n"));
+                                               for (k = 0;k <= 2; k++){
+                                                       //====== RX mode TXK (RXK Step 1) ======
+                                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+                                                       // 1. TX RF Setting
+                                                       rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
+                                                       rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
+                                                       rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
+                                                       rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
+                                                       rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
+                                                       rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
+                                                       rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
+
+                                                       rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
+                                                       rtl_write_dword(rtlpriv, 0x978, 0x29002000);// TX (X,Y)
+                                                       rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);// RX (X,Y)
+                                                       rtl_write_dword(rtlpriv, 0x984, 0x0046a910);// [0]:AGC_en, [15]:idac_K_Mask
+                                                       rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
+                                                       rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
+                                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+                                                       switch (k){
+                                                               case 0:
+                                                                       {
+                                                                               rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                                                               rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                                                               rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
+                                                                       }
+                                                                       break;
+                                                               case 1:
+                                                                       {
+                                                                               rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                                                               rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                                                               rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
+                                                                       }
+                                                                       break;
+                                                               case 2:
+                                                                       {
+                                                                               RT_TRACE(COMP_IQK, DBG_LOUD, ("VDF_Y[1] = %x;;;VDF_Y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff));
+                                                                               RT_TRACE(COMP_IQK, DBG_LOUD, ("VDF_X[1] = %x;;;VDF_X[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff));
+                                                                               rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
+                                                                               RT_TRACE(COMP_IQK, DBG_LOUD, ("Rx_dt = %d\n", rx_dt[cal]));
+                                                                               rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
+                                                                               rx_dt[cal] = (rx_dt[cal] >> 1 )+(rx_dt[cal] & BIT(0));
+                                                                               rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                                                               rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                                                               rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
+                                                                       }
+                                                                       break;
+                                                               default:
+                                                                       break;
+                                                       }
+                                                       rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
+                                                       rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
+                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);// cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module
+                                                       cal_retry = 0;
+                                                       while(1){
+                                                               // one shot
+                                                               rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
+                                                               rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
+
+                                                               mdelay(10); //Delay 10ms
+                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+                                                               delay_count = 0;
+                                                               while (1){
+                                                                       iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
+                                                                       if ((~iqk_ready)||(delay_count>20)){
+                                                                               break;
+                                                                       }
+                                                                       else{
+                                                                               mdelay(1);
+                                                                               delay_count++;
+                                                                       }
+                                                               }
+
+                                                               if (delay_count < 20){                                                  // If 20ms No Result, then cal_retry++
+                                                                       // ============TXIQK Check==============
+                                                                       tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
+
+                                                                       if (~tx_fail){
+                                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
+                                                                               tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
+                                                                               tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                               tx0iqkok = true;
+                                                                               break;
+                                                                       }
+                                                                       else{
+                                                                               tx0iqkok = false;
+                                                                               cal_retry++;
+                                                                               if (cal_retry == 10)
+                                                                                       break;
+                                                                       }
+                                                               }
+                                                               else{
+                                                                       tx0iqkok = false;
+                                                                       cal_retry++;
+                                                                       if (cal_retry == 10)
+                                                                               break;
+                                                               }
+                                                       }
+
+                                                       if (tx0iqkok == false){   //If RX mode TXK fail, then take TXK Result
+                                                               tx_x0_rxk[cal] = tx_x0[cal];
+                                                               tx_y0_rxk[cal] = tx_y0[cal];
+                                                               tx0iqkok = true;
+                                                               RT_TRACE(COMP_IQK, DBG_LOUD, ("RXK Step 1 fail\n"));
+                                                       }
+
+
+                                                       //====== RX IQK ======
+                                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+                                                       // 1. RX RF Setting
+                                                       rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
+                                                       rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
+                                                       rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
+                                                       rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
+                                                       rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
+                                                       rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
+                                                       rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
+
+                                                       rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
+                                                       rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
+                                                       rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
+                                                       rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
+                                                       rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
+                                                       rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
+                                                       rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
+
+                                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+                                                       rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
+                                                       rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
+                                                       rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
+
+                                                       rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
+
+                                                       if (k==2){
+                                                               rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1);  //RX VDF Enable
+                                                       }
+                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);// cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module
+
+                                                       cal_retry = 0;
+                                                       while(1){
+                                                               // one shot
+                                                               rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
+                                                               rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
+
+                                                               mdelay(10); //Delay 10ms
+                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+                                                               delay_count = 0;
+                                                               while (1){
+                                                                       iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
+                                                                       if ((~iqk_ready)||(delay_count>20)){
+                                                                               break;
+                                                                       }
+                                                                       else{
+                                                                               mdelay(1);
+                                                                               delay_count++;
+                                                                       }
+                                                               }
+
+                                                               if (delay_count < 20){  // If 20ms No Result, then cal_retry++
+                                                                       // ============RXIQK Check==============
+                                                                       rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
+                                                                       if (rx_fail == 0){
+                                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
+                                                                               vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                               rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
+                                                                               vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                               rx0iqkok = true;
+                                                                               break;
+                                                                       }
+                                                                       else{
+                                                                               rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
+                                                                               rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
+                                                                               rx0iqkok = false;
+                                                                               cal_retry++;
+                                                                               if (cal_retry == 10)
+                                                                                       break;
+
+                                                                       }
+                                                               }
+                                                               else{
+                                                                       rx0iqkok = false;
+                                                                       cal_retry++;
+                                                                       if (cal_retry == 10)
+                                                                               break;
+                                                               }
+                                                       }
+
+                                               }
+                                               if (k == 3){
+                                                       rx_x0[cal] = vdf_x[k-1] ;
+                                                       rx_y0[cal] = vdf_y[k-1];
+                                               }
+                                               rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);    // TX VDF Enable
+                                       }
+
+                                       else{
+                                               //====== RX mode TXK (RXK Step 1) ======
+                                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+                                               // 1. TX RF Setting
+                                               rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
+                                               rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
+                                               rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
+                                               rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
+                                               rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
+                                               rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
+                                               rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
+                                               rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
+                                               rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
+                                               rtl_write_dword(rtlpriv, 0x984, 0x0046a910);// [0]:AGC_en, [15]:idac_K_Mask
+
+                                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+                                               rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                               rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                               rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
+                                               //ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96);
+                                               rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);// cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module
+                                               cal_retry = 0;
+                                               while(1){
+                                                       // one shot
+                                                       rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
+                                                       rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
+
+                                                       mdelay(10); //Delay 10ms
+                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+                                                       delay_count = 0;
+                                                       while (1){
+                                                               iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
+                                                               if ((~iqk_ready)||(delay_count>20)){
+                                                                       break;
+                                                               }
+                                                               else{
+                                                                       mdelay(1);
+                                                                       delay_count++;
+                                                               }
+                                                       }
+
+                                                       if (delay_count < 20){                                                  // If 20ms No Result, then cal_retry++
+                                                               // ============TXIQK Check==============
+                                                               tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
+
+                                                               if (~tx_fail){
+                                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
+                                                                       tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
+                                                                       tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                       tx0iqkok = true;
+                                                                       break;
+                                                               }
+                                                               else{
+                                                                       tx0iqkok = false;
+                                                                       cal_retry++;
+                                                                       if (cal_retry == 10)
+                                                                               break;
+                                                               }
+                                                       }
+                                                       else{
+                                                               tx0iqkok = false;
+                                                               cal_retry++;
+                                                               if (cal_retry == 10)
+                                                                       break;
+                                                       }
+                                               }
+
+
+                                               if (tx0iqkok == false){   //If RX mode TXK fail, then take TXK Result
+                                                       tx_x0_rxk[cal] = tx_x0[cal];
+                                                       tx_y0_rxk[cal] = tx_y0[cal];
+                                                       tx0iqkok = true;
+                                                       RT_TRACE(COMP_IQK, DBG_LOUD, ("1"));
+                                               }
+
+
+                                               //====== RX IQK ======
+                                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+                                               // 1. RX RF Setting
+                                               rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
+                                               rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
+                                               rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
+                                               rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
+                                               rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
+                                               rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
+                                               rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
+
+                                               rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
+                                               rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
+                                               rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
+                                               rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
+                                               //ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe);
+                                               rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
+                                               rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
+
+                                               rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+                                               rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);// TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16
+                                               rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);// RX_Tone_idx[9:0], RxK_Mask[29]
+                                               rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
+
+                                               rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
+
+                                               rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);// cb8[20] ±N SI/PI ¨Ï¥ÎÅv¤Áµ¹ iqk_dpk module
+
+                                               cal_retry = 0;
+                                               while(1){
+                                                       // one shot
+                                                       rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
+                                                       rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
+
+                                                       mdelay(10); //Delay 10ms
+                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
+                                                       delay_count = 0;
+                                                       while (1){
+                                                               iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
+                                                               if ((~iqk_ready)||(delay_count>20)){
+                                                                       break;
+                                                               }
+                                                               else{
+                                                                       mdelay(1);
+                                                                       delay_count++;
+                                                               }
+                                                       }
+
+                                                       if (delay_count < 20){  // If 20ms No Result, then cal_retry++
+                                                               // ============RXIQK Check==============
+                                                               rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
+                                                               if (rx_fail == 0){
+                                                                       /*
+                                                                          ODM_Write4Byte(pDM_Odm, 0xcb8, 0x05000000);
+                                                                          reg1 = ODM_GetBBReg(pDM_Odm, 0xd00, 0xffffffff);
+                                                                          ODM_Write4Byte(pDM_Odm, 0xcb8, 0x06000000);
+                                                                          reg2 = ODM_GetBBReg(pDM_Odm, 0xd00, 0x0000001f);
+                                                                          DbgPrint("reg1 = %d, reg2 = %d", reg1, reg2);
+                                                                          Image_Power = (reg2<<32)+reg1;
+                                                                          DbgPrint("Before PW = %d\n", Image_Power);
+                                                                          ODM_Write4Byte(pDM_Odm, 0xcb8, 0x07000000);
+                                                                          reg1 = ODM_GetBBReg(pDM_Odm, 0xd00, 0xffffffff);
+                                                                          ODM_Write4Byte(pDM_Odm, 0xcb8, 0x08000000);
+                                                                          reg2 = ODM_GetBBReg(pDM_Odm, 0xd00, 0x0000001f);
+                                                                          Image_Power = (reg2<<32)+reg1;
+                                                                          DbgPrint("After PW = %d\n", Image_Power);
+                                                                          */
+
+                                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
+                                                                       rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                       rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
+                                                                       rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
+                                                                       rx0iqkok = true;
+                                                                       break;
+                                                               }
+                                                               else{
+                                                                       rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
+                                                                       rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
+                                                                       rx0iqkok = false;
+                                                                       cal_retry++;
+                                                                       if (cal_retry == 10)
+                                                                               break;
+
+                                                               }
+                                                       }
+                                                       else{
+                                                               rx0iqkok = false;
+                                                               cal_retry++;
+                                                               if (cal_retry == 10)
+                                                                       break;
+                                                       }
+                                               }
+                                       }
+
+                                       if (tx0iqkok)
+                                               tx_average++;
+                                       if (rx0iqkok)
+                                               rx_average++;
+                                       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+                                       rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
+                               }
+                               break;
+                       default:
+                               break;
+               }
+               cal++;
+       }
+
+       // FillIQK Result
+       switch (path){
+               case RF90_PATH_A:
+                       {
+                               RT_TRACE(COMP_IQK, DBG_LOUD, ("========Path_A =======\n"));
+                               if (tx_average == 0)
+                                       break;
+
+                               for (i = 0; i < tx_average; i++){
+                                       RT_TRACE(COMP_IQK, DBG_LOUD, (" TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i, (tx_x0_rxk[i])>>21&0x000007ff, i, (tx_y0_rxk[i])>>21&0x000007ff));
+                                       RT_TRACE(COMP_IQK, DBG_LOUD, ("TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i, (tx_x0[i])>>21&0x000007ff, i, (tx_y0[i])>>21&0x000007ff));
+                               }
+                               for (i = 0; i < tx_average; i++){
+                                       for (ii = i+1; ii <tx_average; ii++){
+                                               dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
+                                               if (dx < 3 && dx > -3){
+                                                       dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
+                                                       if (dy < 3 && dy > -3){
+                                                               tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
+                                                               tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
+                                                               tx_finish = 1;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       if (tx_finish == 1)
+                                               break;
+                               }
+
+                               if (tx_finish == 1){
+                                       _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); // ?
+                               }
+                               else{
+                                       _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
+                               }
+
+                               if (rx_average == 0)
+                                       break;
+
+                               for (i = 0; i < rx_average; i++){
+                                       RT_TRACE(COMP_IQK, DBG_LOUD, ("RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i, (rx_x0[i])>>21&0x000007ff, i, (rx_y0[i])>>21&0x000007ff));
+                               }
+                               for (i = 0; i < rx_average; i++){
+                                       for (ii = i+1; ii <rx_average; ii++){
+                                               dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
+                                               if (dx < 4 && dx > -4){
+                                                       dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
+                                                       if (dy < 4 && dy > -4){
+                                                               rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
+                                                               rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
+                                                               rx_finish = 1;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       if (rx_finish == 1)
+                                               break;
+                               }
+
+                               if (rx_finish == 1){
+                                       _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
+                               }
+                               else{
+                                       _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
+                               }
+                       }
+                       break;
+               default:
+                       break;
+       }
+}
+
+void _rtl8821ae_iqk_restore_rf(
+               struct ieee80211_hw *hw,
+               enum radio_path path,
+               u32*                    backup_rf_reg,
+               u32*                    rf_backup,
+               u32                     rf_reg_num
+               )
+{
+       u32 i;
+       struct rtl_priv* rtlpriv = rtl_priv(hw);
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+       for (i = 0; i < RF_REG_NUM; i++)
+               rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK, rf_backup[i]);
+
+       switch(path){
+               case RF90_PATH_A:
+                       {
+                               RT_TRACE(COMP_IQK, DBG_LOUD, ("RestoreRF Path A Success!!!!\n"));
+                       }
+                       break;
+               default:
+                       break;
+       }
+}
+
+void _rtl8821ae_iqk_restore_afe(
+               struct ieee80211_hw *hw,
+               u32*            afe_backup,
+               u32*            backup_afe_reg,
+               u32             afe_num
+               )
+{
+       u32 i;
+       struct rtl_priv* rtlpriv = rtl_priv(hw);
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+       //Reload AFE Parameters
+       for (i = 0; i < afe_num; i++){
+               rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
+       }
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); // [31] = 1 --> Page C1
+       rtl_write_dword(rtlpriv, 0xc80, 0x0);
+       rtl_write_dword(rtlpriv, 0xc84, 0x0);
+       rtl_write_dword(rtlpriv, 0xc88, 0x0);
+       rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
+       rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
+       rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
+       rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
+       rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
+       rtl_write_dword(rtlpriv, 0xcb8, 0x0);
+       RT_TRACE(COMP_IQK, DBG_LOUD, ("RestoreAFE Success!!!!\n"));
+}
+
+void _rtl8821ae_iqk_restore_macbb(
+               struct ieee80211_hw *hw,
+               u32*            macbb_backup,
+               u32*            backup_macbb_reg,
+               u32             macbb_num
+               )
+{
+       u32 i;
+       struct rtl_priv* rtlpriv = rtl_priv(hw);
+
+       rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); // [31] = 0 --> Page C
+       //Reload MacBB Parameters
+       for (i = 0; i < macbb_num; i++){
+               rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
+       }
+       RT_TRACE(COMP_IQK, DBG_LOUD, ("RestoreMacBB Success!!!!\n"));
+}
+
+
+#undef MACBB_REG_NUM
+#undef AFE_REG_NUM
+#undef RF_REG_NUM
+
+#define MACBB_REG_NUM 11
+#define AFE_REG_NUM 12
+#define RF_REG_NUM 3
+
+static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
+{
+       u32     macbb_backup[MACBB_REG_NUM];
+       u32 afe_backup[AFE_REG_NUM];
+       u32 rfa_backup[RF_REG_NUM];
+       u32 rfb_backup[RF_REG_NUM];
+       u32     backup_macbb_reg[MACBB_REG_NUM] = {0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
+                                                       0xe00, 0xe50, 0x838, 0x82c};
+       u32     backup_afe_reg[AFE_REG_NUM] = {0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
+                                                       0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8};
+       u32     backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
+
+       _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg, MACBB_REG_NUM);
+       _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
+       _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg, RF_REG_NUM);
+
+       _rtl8821ae_iqk_configure_mac(hw);
+       _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
+       _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup, RF_REG_NUM);
+
+       _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
+       _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg, MACBB_REG_NUM);
+}
+
+static void _rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
+{
+       u8 tmpreg;
+       u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       tmpreg = rtl_read_byte(rtlpriv, 0xd03);
+
+       if ((tmpreg & 0x70) != 0)
+               rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
+       else
+               rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+
+       if ((tmpreg & 0x70) != 0) {
+               rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
+
+               if (is2t)
+                       rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
+                                                 MASK12BITS);
+
+               rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
+                             (rf_a_mode & 0x8FFFF) | 0x10000);
+
+               if (is2t)
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
+                                     (rf_b_mode & 0x8FFFF) | 0x10000);
+       }
+       lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
+
+       rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
+       /* rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); */
+       rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
+
+       mdelay(100);
+
+       rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
+
+       if ((tmpreg & 0x70) != 0) {
+               rtl_write_byte(rtlpriv, 0xd03, tmpreg);
+               rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
+
+               if (is2t)
+                       rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, rf_b_mode);
+       } else {
+               rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+       }
+RT_TRACE(COMP_INIT,DBG_LOUD,("\n"));
+
+}
+
+static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       //struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       //struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       RT_TRACE(COMP_INIT,DBG_LOUD,("\n"));
+
+       if (main)
+               rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
+       else
+               rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
+}
+
+#undef IQK_ADDA_REG_NUM
+#undef IQK_DELAY_TIME
+
+void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       if (!rtlphy->b_iqk_in_progress)
+       {
+               spin_lock(&rtlpriv->locks.iqk_lock);
+               rtlphy->b_iqk_in_progress = true;
+               spin_unlock(&rtlpriv->locks.iqk_lock);
+
+               _rtl8812ae_phy_iq_calibrate(hw, rtlphy->current_channel);
+
+               spin_lock(&rtlpriv->locks.iqk_lock);
+               rtlphy->b_iqk_in_progress = false;
+               spin_unlock(&rtlpriv->locks.iqk_lock);
+       }
+}
+
+void rtl8812ae_reset_iqk_result(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 i;
+
+       RT_TRACE(COMP_IQK, DBG_LOUD,
+               ("rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
+               (int)(sizeof(rtlphy->iqk_matrix_regsetting) /
+               sizeof(struct iqk_matrix_regs)),
+               IQK_MATRIX_SETTINGS_NUM));
+
+       for(i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
+               {
+                       rtlphy->iqk_matrix_regsetting[i].value[0][0] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][2] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][4] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][6] = 0x100;
+
+                       rtlphy->iqk_matrix_regsetting[i].value[0][1] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][3] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][5] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][7] = 0x0;
+
+                       rtlphy->iqk_matrix_regsetting[i].b_iqk_done = false;
+
+               }
+       }
+}
+
+void rtl8812ae_do_iqk(struct ieee80211_hw *hw,u8 delta_thermal_index,
+       u8 thermal_value, u8 threshold)
+{
+       struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
+
+       rtl8812ae_reset_iqk_result(hw);
+
+       rtldm->thermalvalue_iqk= thermal_value;
+       rtl8812ae_phy_iq_calibrate(hw, false);
+}
+
+void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       if (!rtlphy->b_iqk_in_progress)
+       {
+               spin_lock(&rtlpriv->locks.iqk_lock);
+               rtlphy->b_iqk_in_progress = true;
+               spin_unlock(&rtlpriv->locks.iqk_lock);
+
+               _rtl8821ae_phy_iq_calibrate(hw);
+
+               spin_lock(&rtlpriv->locks.iqk_lock);
+               rtlphy->b_iqk_in_progress = false;
+               spin_unlock(&rtlpriv->locks.iqk_lock);
+       }
+}
+
+void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 i;
+
+       RT_TRACE(COMP_IQK, DBG_LOUD,
+               ("rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
+               (int)(sizeof(rtlphy->iqk_matrix_regsetting) /
+               sizeof(struct iqk_matrix_regs)),
+               IQK_MATRIX_SETTINGS_NUM));
+
+       for(i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
+               {
+                       rtlphy->iqk_matrix_regsetting[i].value[0][0] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][2] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][4] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][6] = 0x100;
+
+                       rtlphy->iqk_matrix_regsetting[i].value[0][1] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][3] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][5] =
+                               rtlphy->iqk_matrix_regsetting[i].value[0][7] = 0x0;
+
+                       rtlphy->iqk_matrix_regsetting[i].b_iqk_done = false;
+
+               }
+       }
+}
+
+void rtl8821ae_do_iqk(struct ieee80211_hw *hw,u8 delta_thermal_index,
+       u8 thermal_value, u8 threshold)
+{
+       struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
+
+       rtl8821ae_reset_iqk_result(hw);
+
+       rtldm->thermalvalue_iqk= thermal_value;
+       rtl8821ae_phy_iq_calibrate(hw, false);
+}
+
+void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u32 timeout = 2000, timecount = 0;
+
+
+       while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
+               udelay(50);
+               timecount += 50;
+       }
+
+       rtlphy->lck_inprogress = true;
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("LCK:Start!!! currentband %x delay %d ms\n",
+                rtlhal->current_bandtype, timecount));
+
+       _rtl8821ae_phy_lc_calibrate(hw, false);
+
+       rtlphy->lck_inprogress = false;
+}
+
+void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       if (rtlphy->b_apk_done)
+               return;
+
+       return;
+}
+
+void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
+{
+       _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
+}
+
+bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       bool b_postprocessing = false;
+
+       RT_TRACE(COMP_CMD, DBG_TRACE,
+                ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
+                 iotype, rtlphy->set_io_inprogress));
+       do {
+               switch (iotype) {
+               case IO_CMD_RESUME_DM_BY_SCAN:
+                       RT_TRACE(COMP_CMD, DBG_TRACE,
+                                ("[IO CMD] Resume DM after scan.\n"));
+                       b_postprocessing = true;
+                       break;
+               case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
+               case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
+                       RT_TRACE(COMP_CMD, DBG_TRACE,
+                                ("[IO CMD] Pause DM before scan.\n"));
+                       b_postprocessing = true;
+                       break;
+               default:
+                       RT_TRACE(COMP_ERR, DBG_EMERG,
+                                ("switch case not process \n"));
+                       break;
+               }
+       } while (false);
+       if (b_postprocessing && !rtlphy->set_io_inprogress) {
+               rtlphy->set_io_inprogress = true;
+               rtlphy->current_io_type = iotype;
+       } else {
+               return false;
+       }
+       rtl8821ae_phy_set_io(hw);
+       RT_TRACE(COMP_CMD, DBG_TRACE, ("IO Type(%#x)\n", iotype));
+       return true;
+}
+
+static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       RT_TRACE(COMP_CMD, DBG_TRACE,
+                ("--->Cmd(%#x), set_io_inprogress(%d)\n",
+                 rtlphy->current_io_type, rtlphy->set_io_inprogress));
+       switch (rtlphy->current_io_type) {
+       case IO_CMD_RESUME_DM_BY_SCAN:
+               if (rtlpriv->mac80211.opmode== NL80211_IFTYPE_ADHOC)
+                       _rtl8821ae_resume_tx_beacon(hw);
+               rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
+               rtl8821ae_dm_write_cck_cca_thres(hw, rtlphy->initgain_backup.cca);
+               break;
+       case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
+               if (rtlpriv->mac80211.opmode== NL80211_IFTYPE_ADHOC)
+                       _rtl8821ae_stop_tx_beacon(hw);
+               rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue;
+               rtl8821ae_dm_write_dig(hw, 0x17);
+               rtlphy->initgain_backup.cca = dm_digtable.cur_cck_cca_thres;
+               rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
+               break;
+       case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               break;
+       }
+       rtlphy->set_io_inprogress = false;
+       RT_TRACE(COMP_CMD, DBG_TRACE,
+                ("(%#x)\n", rtlphy->current_io_type));
+}
+
+static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+       rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+}
+
+#if 0
+static void _rtl8821ae_phy_set_rf_sleep(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+       rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+       /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+       u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
+       while (u4b_tmp != 0 && delay > 0) {
+               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
+               rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+               u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
+               delay--;
+       }
+       if (delay == 0) {
+               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
+               rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+               rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+               rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+               RT_TRACE(COMP_POWER, DBG_TRACE,
+                        ("Switch RF timeout !!!.\n"));
+               return;
+       }*/
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+       rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
+}
+#endif
+
+static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
+                                           enum rf_pwrstate rfpwr_state)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       bool bresult = true;
+       u8 i, queue_id;
+       struct rtl8192_tx_ring *ring = NULL;
+
+       switch (rfpwr_state) {
+       case ERFON:{
+                       if ((ppsc->rfpwr_state == ERFOFF) &&
+                           RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
+                               bool rtstatus = false;
+                               u32 InitializeCount = 0;
+                               do {
+                                       InitializeCount++;
+                                       RT_TRACE(COMP_RF, DBG_DMESG,
+                                                ("IPS Set eRf nic enable\n"));
+                                       rtstatus = rtl_ps_enable_nic(hw);
+                               } while ((rtstatus != true)
+                                        && (InitializeCount < 10));
+                               RT_CLEAR_PS_LEVEL(ppsc,
+                                                 RT_RF_OFF_LEVL_HALT_NIC);
+                       } else {
+                               RT_TRACE(COMP_RF, DBG_DMESG,
+                                        ("Set ERFON sleeped:%d ms\n",
+                                         jiffies_to_msecs(jiffies -
+                                                          ppsc->
+                                                          last_sleep_jiffies)));
+                               ppsc->last_awake_jiffies = jiffies;
+                               rtl8821ae_phy_set_rf_on(hw);
+                       }
+                       if (mac->link_state == MAC80211_LINKED) {
+                               rtlpriv->cfg->ops->led_control(hw,
+                                                              LED_CTL_LINK);
+                       } else {
+                               rtlpriv->cfg->ops->led_control(hw,
+                                                              LED_CTL_NO_LINK);
+                       }
+                       break;
+               }
+       case ERFOFF:{
+                       for (queue_id = 0, i = 0;
+                            queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
+                               ring = &pcipriv->dev.tx_ring[queue_id];
+                               if (skb_queue_len(&ring->queue) == 0) {
+                                       queue_id++;
+                                       continue;
+                               } else {
+                                       RT_TRACE(COMP_ERR, DBG_WARNING,
+                                                ("eRf Off/Sleep: %d times "
+                                                 "TcbBusyQueue[%d] =%d before "
+                                                 "doze!\n", (i + 1), queue_id,
+                                                 skb_queue_len(&ring->queue)));
+
+                                       udelay(10);
+                                       i++;
+                               }
+                               if (i >= MAX_DOZE_WAITING_TIMES_9x) {
+                                       RT_TRACE(COMP_ERR, DBG_WARNING,
+                                                ("\n ERFSLEEP: %d times "
+                                                 "TcbBusyQueue[%d] = %d !\n",
+                                                 MAX_DOZE_WAITING_TIMES_9x,
+                                                 queue_id,
+                                                 skb_queue_len(&ring->queue)));
+                                       break;
+                               }
+                       }
+
+                       if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
+                               RT_TRACE(COMP_RF, DBG_DMESG,
+                                        ("IPS Set eRf nic disable\n"));
+                               rtl_ps_disable_nic(hw);
+                               RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+                       } else {
+                               if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
+                                       rtlpriv->cfg->ops->led_control(hw,
+                                                                      LED_CTL_NO_LINK);
+                               } else {
+                                       rtlpriv->cfg->ops->led_control(hw,
+                                                                      LED_CTL_POWER_OFF);
+                               }
+                       }
+                       break;
+               }
+       /*case ERFSLEEP:{
+                       if (ppsc->rfpwr_state == ERFOFF)
+                               break;
+                       for (queue_id = 0, i = 0;
+                            queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
+                               ring = &pcipriv->dev.tx_ring[queue_id];
+                               if (skb_queue_len(&ring->queue) == 0) {
+                                       queue_id++;
+                                       continue;
+                               } else {
+                                       RT_TRACE(COMP_ERR, DBG_WARNING,
+                                                ("eRf Off/Sleep: %d times "
+                                                 "TcbBusyQueue[%d] =%d before "
+                                                 "doze!\n", (i + 1), queue_id,
+                                                 skb_queue_len(&ring->queue)));
+
+                                       udelay(10);
+                                       i++;
+                               }
+                               if (i >= MAX_DOZE_WAITING_TIMES_9x) {
+                                       RT_TRACE(COMP_ERR, DBG_WARNING,
+                                                ("\n ERFSLEEP: %d times "
+                                                 "TcbBusyQueue[%d] = %d !\n",
+                                                 MAX_DOZE_WAITING_TIMES_9x,
+                                                 queue_id,
+                                                 skb_queue_len(&ring->queue)));
+                                       break;
+                               }
+                       }
+                       RT_TRACE(COMP_RF, DBG_DMESG,
+                                ("Set ERFSLEEP awaked:%d ms\n",
+                                 jiffies_to_msecs(jiffies -
+                                                  ppsc->last_awake_jiffies)));
+                       ppsc->last_sleep_jiffies = jiffies;
+                       _rtl8821ae_phy_set_rf_sleep(hw);
+                       break;
+               }*/
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("switch case not process \n"));
+               bresult = false;
+               break;
+       }
+       if (bresult)
+               ppsc->rfpwr_state = rfpwr_state;
+       return bresult;
+}
+
+bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
+                                  enum rf_pwrstate rfpwr_state)
+{
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       bool bresult = false;
+
+       if (rfpwr_state == ppsc->rfpwr_state)
+               return bresult;
+       bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);
+       return bresult;
+}
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/phy.h b/drivers/staging/rtl8821ae/rtl8821ae/phy.h
new file mode 100644 (file)
index 0000000..a932d8c
--- /dev/null
@@ -0,0 +1,258 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_PHY_H__
+#define __RTL8821AE_PHY_H__
+
+/*It must always set to 4, otherwise read efuse table secquence will be wrong.*/
+#define MAX_TX_COUNT   4
+#define        TX_1S                   0
+#define        TX_2S                   1
+#define        TX_3S                   2
+#define        TX_4S                   3
+
+#define        MAX_POWER_INDEX 0x3F
+
+#define MAX_PRECMD_CNT                                 16
+#define MAX_RFDEPENDCMD_CNT            16
+#define MAX_POSTCMD_CNT                        16
+
+#define MAX_DOZE_WAITING_TIMES_9x      64
+
+#define RT_CANNOT_IO(hw)                       false
+#define HIGHPOWER_RADIOA_ARRAYLEN      22
+
+#define IQK_ADDA_REG_NUM                       16
+#define IQK_BB_REG_NUM                         9
+#define MAX_TOLERANCE                          5
+#define        IQK_DELAY_TIME                          10
+#define        index_mapping_NUM       15
+
+#define        APK_BB_REG_NUM                          5
+#define        APK_AFE_REG_NUM                         16
+#define        APK_CURVE_REG_NUM                       4
+#define        PATH_NUM                                        2
+
+#define LOOP_LIMIT                                     5
+#define MAX_STALL_TIME                         50
+#define AntennaDiversityValue          0x80
+#define MAX_TXPWR_IDX_NMODE_92S                63
+#define Reset_Cnt_Limit                                3
+
+#define IQK_ADDA_REG_NUM                       16
+#define IQK_MAC_REG_NUM                                4
+
+#define RF6052_MAX_PATH                                2
+
+#define CT_OFFSET_MAC_ADDR                     0X16
+
+#define CT_OFFSET_CCK_TX_PWR_IDX                       0x5A
+#define CT_OFFSET_HT401S_TX_PWR_IDX                    0x60
+#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF       0x66
+#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF         0x69
+#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF         0x6C
+
+#define CT_OFFSET_HT40_MAX_PWR_OFFSET          0x6F
+#define CT_OFFSET_HT20_MAX_PWR_OFFSET          0x72
+
+#define CT_OFFSET_CHANNEL_PLAH                         0x75
+#define CT_OFFSET_THERMAL_METER                                0x78
+#define CT_OFFSET_RF_OPTION                                    0x79
+#define CT_OFFSET_VERSION                                      0x7E
+#define CT_OFFSET_CUSTOMER_ID                          0x7F
+
+#define RTL8821AE_MAX_PATH_NUM                                 2
+
+#define TARGET_CHNL_NUM_2G_5G_8812     59
+
+enum swchnlcmd_id {
+       CMDID_END,
+       CMDID_SET_TXPOWEROWER_LEVEL,
+       CMDID_BBREGWRITE10,
+       CMDID_WRITEPORT_ULONG,
+       CMDID_WRITEPORT_USHORT,
+       CMDID_WRITEPORT_UCHAR,
+       CMDID_RF_WRITEREG,
+};
+
+struct swchnlcmd {
+       enum swchnlcmd_id cmdid;
+       u32 para1;
+       u32 para2;
+       u32 msdelay;
+};
+
+enum hw90_block_e {
+       HW90_BLOCK_MAC = 0,
+       HW90_BLOCK_PHY0 = 1,
+       HW90_BLOCK_PHY1 = 2,
+       HW90_BLOCK_RF = 3,
+       HW90_BLOCK_MAXIMUM = 4,
+};
+
+enum baseband_config_type {
+       BASEBAND_CONFIG_PHY_REG = 0,
+       BASEBAND_CONFIG_AGC_TAB = 1,
+};
+
+enum ra_offset_area {
+       RA_OFFSET_LEGACY_OFDM1,
+       RA_OFFSET_LEGACY_OFDM2,
+       RA_OFFSET_HT_OFDM1,
+       RA_OFFSET_HT_OFDM2,
+       RA_OFFSET_HT_OFDM3,
+       RA_OFFSET_HT_OFDM4,
+       RA_OFFSET_HT_CCK,
+};
+
+enum antenna_path {
+       ANTENNA_NONE,
+       ANTENNA_D,
+       ANTENNA_C,
+       ANTENNA_CD,
+       ANTENNA_B,
+       ANTENNA_BD,
+       ANTENNA_BC,
+       ANTENNA_BCD,
+       ANTENNA_A,
+       ANTENNA_AD,
+       ANTENNA_AC,
+       ANTENNA_ACD,
+       ANTENNA_AB,
+       ANTENNA_ABD,
+       ANTENNA_ABC,
+       ANTENNA_ABCD
+};
+
+struct r_antenna_select_ofdm {
+       u32 r_tx_antenna:4;
+       u32 r_ant_l:4;
+       u32 r_ant_non_ht:4;
+       u32 r_ant_ht1:4;
+       u32 r_ant_ht2:4;
+       u32 r_ant_ht_s1:4;
+       u32 r_ant_non_ht_s1:4;
+       u32 ofdm_txsc:2;
+       u32 reserved:2;
+};
+
+struct r_antenna_select_cck {
+       u8 r_cckrx_enable_2:2;
+       u8 r_cckrx_enable:2;
+       u8 r_ccktx_enable:4;
+};
+
+
+struct efuse_contents {
+       u8 mac_addr[ETH_ALEN];
+       u8 cck_tx_power_idx[6];
+       u8 ht40_1s_tx_power_idx[6];
+       u8 ht40_2s_tx_power_idx_diff[3];
+       u8 ht20_tx_power_idx_diff[3];
+       u8 ofdm_tx_power_idx_diff[3];
+       u8 ht40_max_power_offset[3];
+       u8 ht20_max_power_offset[3];
+       u8 channel_plan;
+       u8 thermal_meter;
+       u8 rf_option[5];
+       u8 version;
+       u8 oem_id;
+       u8 regulatory;
+};
+
+struct tx_power_struct {
+       u8 cck[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+       u8 ht40_1s[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+       u8 ht40_2s[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+       u8 ht20_diff[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+       u8 legacy_ht_diff[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+       u8 legacy_ht_txpowerdiff;
+       u8 groupht20[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+       u8 groupht40[RTL8821AE_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
+       u8 pwrgroup_cnt;
+       u32 mcs_original_offset[4][16];
+};
+enum _ANT_DIV_TYPE
+{
+       NO_ANTDIV                               = 0xFF,
+       CG_TRX_HW_ANTDIV                = 0x01,
+       CGCS_RX_HW_ANTDIV               = 0x02,
+       FIXED_HW_ANTDIV         = 0x03,
+       CG_TRX_SMART_ANTDIV             = 0x04,
+       CGCS_RX_SW_ANTDIV               = 0x05,
+
+};
+
+extern u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw,
+                                  u32 regaddr, u32 bitmask);
+extern void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw,
+                                 u32 regaddr, u32 bitmask, u32 data);
+extern u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw,
+                                  enum radio_path rfpath, u32 regaddr,
+                                  u32 bitmask);
+extern void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw,
+                                 enum radio_path rfpath, u32 regaddr,
+                                 u32 bitmask, u32 data);
+extern bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw);
+extern bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw);
+extern bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw);
+extern void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band);
+extern void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+extern void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw,
+                                        long *powerlevel);
+extern void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
+extern void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw,
+                                            u8 operation);
+extern void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+extern void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
+                                  enum nl80211_channel_type ch_type);
+extern void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw);
+extern u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw);
+extern void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+extern void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
+void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw);
+void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
+bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+                                         enum radio_path rfpath);
+bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+                                         enum radio_path rfpath);
+bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
+extern bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
+                                         enum rf_pwrstate rfpwr_state);
+u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl);
+void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, u8 channel, u8 path);
+void rtl8812ae_do_iqk(struct ieee80211_hw *hw,u8 delta_thermal_index,
+       u8 thermal_value, u8 threshold);
+void rtl8821ae_do_iqk(struct ieee80211_hw *hw,u8 delta_thermal_index,
+       u8 thermal_value, u8 threshold);
+void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw);
+
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/pwrseq.c b/drivers/staging/rtl8821ae/rtl8821ae/pwrseq.c
new file mode 100644 (file)
index 0000000..a2e4a01
--- /dev/null
@@ -0,0 +1,199 @@
+/******************************************************************************
+ *
+ * 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 "pwrseqcmd.h"
+#include "pwrseq.h"
+
+/*
+    drivers should parse below arrays and do the corresponding actions
+*/
+//3 Power on  Array
+struct wlan_pwr_cfg rtl8812_power_on_flow[RTL8812_TRANS_CARDEMU_TO_ACT_STEPS+RTL8812_TRANS_END_STEPS]=
+{
+       RTL8812_TRANS_CARDEMU_TO_ACT
+       RTL8812_TRANS_END
+};
+
+//3Radio off GPIO Array
+struct wlan_pwr_cfg rtl8812_radio_off_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_END_STEPS]=
+{
+       RTL8812_TRANS_ACT_TO_CARDEMU
+       RTL8812_TRANS_END
+};
+
+//3Card Disable Array
+struct wlan_pwr_cfg rtl8812_card_disable_flow[ RTL8812_TRANS_ACT_TO_CARDEMU_STEPS
+       + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS
+       + RTL8812_TRANS_END_STEPS ] =
+{
+       RTL8812_TRANS_ACT_TO_CARDEMU
+       RTL8812_TRANS_CARDEMU_TO_CARDDIS
+       RTL8812_TRANS_END
+};
+
+//3 Card Enable Array
+struct wlan_pwr_cfg rtl8812_card_enable_flow[ RTL8812_TRANS_ACT_TO_CARDEMU_STEPS
+       + RTL8812_TRANS_CARDEMU_TO_PDN_STEPS
+       + RTL8812_TRANS_END_STEPS ] =
+{
+       RTL8812_TRANS_CARDDIS_TO_CARDEMU
+       RTL8812_TRANS_CARDEMU_TO_ACT
+       RTL8812_TRANS_END
+};
+
+//3Suspend Array
+struct wlan_pwr_cfg rtl8812_suspend_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_SUS_STEPS+RTL8812_TRANS_END_STEPS]=
+{
+       RTL8812_TRANS_ACT_TO_CARDEMU
+       RTL8812_TRANS_CARDEMU_TO_SUS
+       RTL8812_TRANS_END
+};
+
+//3 Resume Array
+struct wlan_pwr_cfg rtl8812_resume_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_SUS_STEPS+RTL8812_TRANS_END_STEPS]=
+{
+       RTL8812_TRANS_SUS_TO_CARDEMU
+       RTL8812_TRANS_CARDEMU_TO_ACT
+       RTL8812_TRANS_END
+};
+
+
+
+//3HWPDN Array
+struct wlan_pwr_cfg rtl8812_hwpdn_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_PDN_STEPS+RTL8812_TRANS_END_STEPS]=
+{
+       RTL8812_TRANS_ACT_TO_CARDEMU
+       RTL8812_TRANS_CARDEMU_TO_PDN
+       RTL8812_TRANS_END
+};
+
+//3 Enter LPS
+struct wlan_pwr_cfg rtl8812_enter_lps_flow[RTL8812_TRANS_ACT_TO_LPS_STEPS+RTL8812_TRANS_END_STEPS]=
+{
+       //FW behavior
+       RTL8812_TRANS_ACT_TO_LPS
+       RTL8812_TRANS_END
+};
+
+//3 Leave LPS
+struct wlan_pwr_cfg rtl8812_leave_lps_flow[RTL8812_TRANS_LPS_TO_ACT_STEPS+RTL8812_TRANS_END_STEPS]=
+{
+       //FW behavior
+       RTL8812_TRANS_LPS_TO_ACT
+       RTL8812_TRANS_END
+};
+
+
+/*
+    drivers should parse below arrays and do the corresponding actions
+*/
+/*3 Power on  Array*/
+struct wlan_pwr_cfg rtl8821A_power_on_flow[RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS
+                                       + RTL8821A_TRANS_END_STEPS] =
+{
+       RTL8821A_TRANS_CARDEMU_TO_ACT
+       RTL8821A_TRANS_END
+};
+
+/*3Radio off GPIO Array */
+struct wlan_pwr_cfg rtl8821A_radio_off_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                       + RTL8821A_TRANS_END_STEPS] =
+{
+       RTL8821A_TRANS_ACT_TO_CARDEMU
+       RTL8821A_TRANS_END
+};
+
+/*3Card Disable Array*/
+struct wlan_pwr_cfg rtl8821A_card_disable_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                       + RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS
+                                       + RTL8821A_TRANS_END_STEPS] =
+{
+       RTL8821A_TRANS_ACT_TO_CARDEMU
+       RTL8821A_TRANS_CARDEMU_TO_CARDDIS
+       RTL8821A_TRANS_END
+};
+
+/*3 Card Enable Array*/
+struct wlan_pwr_cfg rtl8821A_card_enable_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                       + RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS /*RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS*/
+                                       + RTL8821A_TRANS_END_STEPS] =
+{
+       RTL8821A_TRANS_CARDDIS_TO_CARDEMU
+       RTL8821A_TRANS_CARDEMU_TO_ACT
+       RTL8821A_TRANS_END
+};
+
+/*3Suspend Array*/
+struct wlan_pwr_cfg rtl8821A_suspend_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                       + RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS
+                                       + RTL8821A_TRANS_END_STEPS] =
+{
+       RTL8821A_TRANS_ACT_TO_CARDEMU
+       RTL8821A_TRANS_CARDEMU_TO_SUS
+       RTL8821A_TRANS_END
+};
+
+/*3 Resume Array*/
+struct wlan_pwr_cfg rtl8821A_resume_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                       + RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS
+                                       + RTL8821A_TRANS_END_STEPS] =
+{
+       RTL8821A_TRANS_SUS_TO_CARDEMU
+       RTL8821A_TRANS_CARDEMU_TO_ACT
+       RTL8821A_TRANS_END
+};
+
+/*3HWPDN Array*/
+struct wlan_pwr_cfg rtl8821A_hwpdn_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                               + RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS
+                               + RTL8821A_TRANS_END_STEPS] =
+{
+       RTL8821A_TRANS_ACT_TO_CARDEMU
+       RTL8821A_TRANS_CARDEMU_TO_PDN
+       RTL8821A_TRANS_END
+};
+
+/*3 Enter LPS */
+struct wlan_pwr_cfg rtl8821A_enter_lps_flow[RTL8821A_TRANS_ACT_TO_LPS_STEPS
+                                       + RTL8821A_TRANS_END_STEPS] =
+{
+       /*FW behavior*/
+       RTL8821A_TRANS_ACT_TO_LPS
+       RTL8821A_TRANS_END
+};
+
+/*3 Leave LPS */
+struct wlan_pwr_cfg rtl8821A_leave_lps_flow[RTL8821A_TRANS_LPS_TO_ACT_STEPS
+                                       + RTL8821A_TRANS_END_STEPS] =
+{
+       /*FW behavior*/
+       RTL8821A_TRANS_LPS_TO_ACT
+       RTL8821A_TRANS_END
+};
+
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/pwrseq.h b/drivers/staging/rtl8821ae/rtl8821ae/pwrseq.h
new file mode 100644 (file)
index 0000000..8b39c04
--- /dev/null
@@ -0,0 +1,413 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_PWRSEQ_H__
+#define __RTL8821AE_PWRSEQ_H__
+
+#include "pwrseqcmd.h"
+#include "../btcoexist/halbt_precomp.h"
+
+#define        RTL8812_TRANS_CARDEMU_TO_ACT_STEPS      15
+#define        RTL8812_TRANS_ACT_TO_CARDEMU_STEPS      15
+#define        RTL8812_TRANS_CARDEMU_TO_SUS_STEPS      15
+#define        RTL8812_TRANS_SUS_TO_CARDEMU_STEPS      15
+#define        RTL8812_TRANS_CARDEMU_TO_PDN_STEPS      25
+#define        RTL8812_TRANS_PDN_TO_CARDEMU_STEPS      15
+#define        RTL8812_TRANS_ACT_TO_LPS_STEPS  15
+#define        RTL8812_TRANS_LPS_TO_ACT_STEPS  15
+#define        RTL8812_TRANS_END_STEPS 1
+
+
+#define RTL8812_TRANS_CARDEMU_TO_ACT                                                                                                           \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* disable SW LPS 0x04[10]=0*/     \
+       {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1    power ready*/    \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/ \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0},/* disable WL suspend*/    \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/     \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/
+
+#define RTL8812_TRANS_ACT_TO_CARDEMU                                                                                                   \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xc00[7:0] = 4      turn off 3-wire */      \
+       {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xe00[7:0] = 4      turn off 3-wire */      \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /* 0x2[0] = 0      RESET BB, CLOSE RF */  \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/   \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},  /* Whole BB is reset*/                   \
+       /*{0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},//0x1F[7:0] = 0 turn off RF*/    \
+       /*{0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},//0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */      \
+       {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x2A}, /* 0x07[7:0] = 0x28 sps pwm mode 0x2a for BT coex*/    \
+       {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk =500k */      \
+       /*{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0|BIT1, 0}, //  0x02[1:0] = 0  reset BB */     \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/       \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/
+
+#define RTL8812_TRANS_CARDEMU_TO_SUS                                                                                                   \
+       /* format */                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xcc},\
+       {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xEC},\
+       {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x07},/* gpio11 input mode, gpio10~8 output mode */   \
+       {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio 0~7 output same value as input ?? */    \
+       {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xff},/* gpio0~7 output mode */       \
+       {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* 0x47[7:0] = 00 gpio mode */     \
+       {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* suspend option all off */       \
+       {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x80, BIT7},/*0x14[7] = 1 turn on ZCD */    \
+       {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, BIT0},/* 0x15[0] =1 trun on ZCD */    \
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, BIT4},/*0x23[4] = 1 hpon LDO sleep mode */    \
+       {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk =500k */      \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /*0x04[11] = 2b'11 enable WL suspend for PCIe*/
+
+#define RTL8812_TRANS_SUS_TO_CARDEMU                                                                                                   \
+       /* format */                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0}, /*0x04[11] = 2b'01enable WL suspend*/   \
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, 0},/*0x23[4] = 0 hpon LDO sleep mode leave */ \
+       {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, 0},/* 0x15[0] =0 trun off ZCD */      \
+       {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x80, 0},/*0x14[7] = 0 turn off ZCD */      \
+       {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio0~7 input mode */        \
+       {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio11 input mode, gpio10~8 input mode */
+
+#define RTL8812_TRANS_CARDEMU_TO_CARDDIS                                                                                                       \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       /**{0x0194, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, //0x194[0]=0 , disable 32K clock*/     \
+       /**{0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x94}, //0x93=0x94 , 90[30] =0 enable 500k ANA clock .switch clock from 12M to 500K , 90 [26] =0 disable EEprom loader clock*/     \
+       {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0}, /*0x03[2] = 0, reset 8051*/       \
+       {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x05}, /*0x80=05h if reload fw, fill the default value of host_CPU handshake field*/  \
+       {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xcc},\
+       {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xEC},\
+       {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x07},/* gpio11 input mode, gpio10~8 output mode */   \
+       {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio 0~7 output same value as input ?? */    \
+       {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xff},/* gpio0~7 output mode */       \
+       {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* 0x47[7:0] = 00 gpio mode */     \
+       {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x80, BIT7},/*0x14[7] = 1 turn on ZCD */    \
+       {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, BIT0},/* 0x15[0] =1 trun on ZCD */    \
+       {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, 0},/*0x12[0] = 0 force PFM mode */    \
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, BIT4},/*0x23[4] = 1 hpon LDO sleep mode */    \
+       {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk =500k */      \
+       {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/    \
+       {0x001f, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /*0x01f[1]=0 , disable RFC_0  control  REG_RF_CTRL_8812 */        \
+       {0x0076, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /*0x076[1]=0 , disable RFC_1  control REG_OPT_CTRL_8812 +2 */     \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /*0x04[11] = 2b'01 enable WL suspend*/
+
+#define RTL8812_TRANS_CARDDIS_TO_CARDEMU                                                                                                       \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                       \
+       {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*0x12[0] = 1 force PWM mode */ \
+       {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x80, 0},/*0x14[7] = 0 turn off ZCD */      \
+       {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, 0},/* 0x15[0] =0 trun off ZCD */      \
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, 0},/*0x23[4] = 0 hpon LDO leave sleep mode */ \
+       {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio0~7 input mode */        \
+       {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio11 input mode, gpio10~8 input mode */ \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0}, /*0x04[10] = 0, enable SW LPS PCIE only*/ \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0}, /*0x04[11] = 2b'01enable WL suspend*/     \
+       {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x03[2] = 1, enable 8051*/   \
+       {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/
+
+
+#define RTL8812_TRANS_CARDEMU_TO_PDN                                                                                           \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/
+
+#define RTL8812_TRANS_PDN_TO_CARDEMU                                                                                           \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/
+
+#define RTL8812_TRANS_ACT_TO_LPS                                                                                                               \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/       \
+       {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/            \
+       {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/  \
+       {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/  \
+       {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/  \
+       {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/  \
+       {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xc00[7:0] = 4      turn off 3-wire */      \
+       {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xe00[7:0] = 4      turn off 3-wire */      \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated,and RF closed*/    \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/   \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},  /* Whole BB is reset*/                   \
+       {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/                       \
+       {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/         \
+       {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/
+
+
+#define RTL8812_TRANS_LPS_TO_ACT                                                                                                                       \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \
+       {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/        \
+       {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/   \
+       {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/  \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/      \
+       {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*.       0x08[4] = 0              switch TSF to 40M*/    \
+       {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0  TSF in 40M*/                      \
+       {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*.  0x29[7:6] = 2b'00        enable BB clock*/      \
+       {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*.    0x101[1] = 1*/                                  \
+       {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*.    0x100[7:0] = 0xFF        enable WMAC TRX*/      \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*.  0x02[1:0] = 2b'11        enable BB macro*/      \
+       {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*.       0x522 = 0*/
+
+#define RTL8812_TRANS_END                                                                                                                              \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/         \
+       {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, //
+
+
+extern struct wlan_pwr_cfg  rtl8812_power_on_flow[RTL8812_TRANS_CARDEMU_TO_ACT_STEPS+RTL8812_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg  rtl8812_radio_off_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg  rtl8812_card_disable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_PDN_STEPS+RTL8812_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg  rtl8812_card_enable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_PDN_STEPS+RTL8812_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg  rtl8812_suspend_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_SUS_STEPS+RTL8812_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg  rtl8812_resume_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_SUS_STEPS+RTL8812_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg  rtl8812_hwpdn_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_PDN_STEPS+RTL8812_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg  rtl8812_enter_lps_flow[RTL8812_TRANS_ACT_TO_LPS_STEPS+RTL8812_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg  rtl8812_leave_lps_flow[RTL8812_TRANS_LPS_TO_ACT_STEPS+RTL8812_TRANS_END_STEPS];
+
+/*
+       Check document WM-20130516-JackieLau-RTL8821A_Power_Architecture-R10.vsd
+       There are 6 HW Power States:
+       0: POFF--Power Off
+       1: PDN--Power Down
+       2: CARDEMU--Card Emulation
+       3: ACT--Active Mode
+       4: LPS--Low Power State
+       5: SUS--Suspend
+
+       The transision from different states are defined below
+       TRANS_CARDEMU_TO_ACT
+       TRANS_ACT_TO_CARDEMU
+       TRANS_CARDEMU_TO_SUS
+       TRANS_SUS_TO_CARDEMU
+       TRANS_CARDEMU_TO_PDN
+       TRANS_ACT_TO_LPS
+       TRANS_LPS_TO_ACT
+
+       TRANS_END
+*/
+#define        RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS     25
+#define        RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS     15
+#define        RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS     15
+#define        RTL8821A_TRANS_SUS_TO_CARDEMU_STEPS     15
+#define RTL8821A_TRANS_CARDDIS_TO_CARDEMU_STEPS        15
+#define        RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS     15
+#define        RTL8821A_TRANS_PDN_TO_CARDEMU_STEPS     15
+#define        RTL8821A_TRANS_ACT_TO_LPS_STEPS 15
+#define        RTL8821A_TRANS_LPS_TO_ACT_STEPS 15
+#define        RTL8821A_TRANS_END_STEPS        1
+
+
+#define RTL8821A_TRANS_CARDEMU_TO_ACT                                                                                                          \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/   \
+       {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/      \
+       {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/   \
+       {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0}, /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/   \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3|BIT2), 0},/* disable SW LPS 0x04[10]=0 and WLSUS_EN 0x04[12:11]=0*/      \
+       {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0 , BIT0},/* Disable USB suspend */      \
+       {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1    power ready*/    \
+       {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0 , 0},/* Enable USB suspend */  \
+       {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset  0x04[16]=1*/     \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/      \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3), 0},/* disable WL suspend*/     \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/     \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/     \
+       {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*0x4C[24] = 0x4F[0] = 1, switch DPDT_SEL_P output from WL BB */\
+       {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT5|BIT4), (BIT5|BIT4)},/*0x66[13] = 0x67[5] = 1, switch for PAPE_G/PAPE_A from WL BB ; 0x66[12] = 0x67[4] = 1, switch LNAON from WL BB */\
+       {0x0025, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, 0},/*anapar_mac<118> , 0x25[6]=0 by wlan single function*/\
+       {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable falling edge triggering interrupt*/\
+       {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable GPIO9 interrupt mode*/\
+       {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable GPIO9 input mode*/\
+       {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Enable HSISR GPIO[C:0] interrupt*/\
+       {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable HSISR GPIO9 interrupt*/\
+       {0x007A, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x3A},/*0x7A = 0x3A start BT*/\
+       {0x002E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF , 0x82 },/* 0x2C[23:12]=0x820 ; XTAL trim */ \
+       {0x0010, PWR_CUT_A_MSK , PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6 , BIT6 },/* 0x10[6]=1 ; MP·s¼W¹ï©ó0x2Cªº±±¨îÅv¡A¶·§â0x10[6]³]¬°1¤~¯àÅýWLAN±±¨î */ \
+
+
+#define RTL8821A_TRANS_ACT_TO_CARDEMU                                                                                                  \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/      \
+       {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*0x4C[24] = 0x4F[0] = 0, switch DPDT_SEL_P output from register 0x65[2] */\
+       {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable rising edge triggering interrupt*/ \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/       \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/     \
+       {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5}, /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/   \
+       {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/   \
+
+
+#define RTL8821A_TRANS_CARDEMU_TO_SUS                                                                                                  \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/       \
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/   \
+       {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/   \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/   \
+       {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/  \
+       {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/
+
+#define RTL8821A_TRANS_SUS_TO_CARDEMU                                                                                                  \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/     \
+       {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/     \
+       {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/   \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/
+
+#define RTL8821A_TRANS_CARDEMU_TO_CARDDIS                                                                                                      \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/   \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/       \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x04[10] = 1, enable SW LPS*/        \
+        {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/   \
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/   \
+       {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/  \
+       {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/
+
+#define RTL8821A_TRANS_CARDDIS_TO_CARDEMU                                                                                                      \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/     \
+       {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/     \
+       {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\
+       {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/   \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/   \
+       {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/
+
+
+#define RTL8821A_TRANS_CARDEMU_TO_PDN                                                                                          \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/   \
+       {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/   \
+       {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/
+
+#define RTL8821A_TRANS_PDN_TO_CARDEMU                                                                                          \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/
+
+#define RTL8821A_TRANS_ACT_TO_LPS                                                                                                              \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/       \
+       {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/    \
+       {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/  \
+       {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/  \
+       {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/  \
+       {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/  \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/  \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/   \
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/      \
+       {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/       \
+       {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \
+       {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/  \
+       {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/   \
+
+
+#define RTL8821A_TRANS_LPS_TO_ACT                                                                                                                      \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\
+       {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\
+       {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\
+       {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*.       0x08[4] = 0              switch TSF to 40M*/\
+       {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0  TSF in 40M*/\
+       {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*.  0x29[7:6] = 2b'00        enable BB clock*/\
+       {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*.    0x101[1] = 1*/\
+       {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*.    0x100[7:0] = 0xFF        enable WMAC TRX*/\
+       {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*.  0x02[1:0] = 2b'11        enable BB macro*/\
+       {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*.       0x522 = 0*/
+
+#define RTL8821A_TRANS_END                                                                                                                     \
+       /* format */                                                                                                                            \
+       /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/                                                         \
+       {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, //
+
+extern struct wlan_pwr_cfg rtl8821A_power_on_flow[RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS
+                                               + RTL8821A_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg rtl8821A_radio_off_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                               + RTL8821A_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg rtl8821A_card_disable_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                               + RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS
+                                               + RTL8821A_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg rtl8821A_card_enable_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                               + RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS/*RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS*/
+                                               + RTL8821A_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg rtl8821A_suspend_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                               + RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS
+                                               + RTL8821A_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg rtl8821A_resume_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                               + RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS
+                                               + RTL8821A_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg rtl8821A_hwpdn_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS
+                                               + RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS
+                                               + RTL8821A_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg rtl8821A_enter_lps_flow[RTL8821A_TRANS_ACT_TO_LPS_STEPS
+                                               + RTL8821A_TRANS_END_STEPS];
+extern struct wlan_pwr_cfg rtl8821A_leave_lps_flow[RTL8821A_TRANS_LPS_TO_ACT_STEPS
+                                               + RTL8821A_TRANS_END_STEPS];
+
+/*RTL8812 Power Configuration CMDs for PCIe interface*/
+#define RTL8812_NIC_PWR_ON_FLOW                                rtl8812_power_on_flow
+#define RTL8812_NIC_RF_OFF_FLOW                                rtl8812_radio_off_flow
+#define RTL8812_NIC_DISABLE_FLOW                       rtl8812_card_disable_flow
+#define RTL8812_NIC_ENABLE_FLOW                                rtl8812_card_enable_flow
+#define RTL8812_NIC_SUSPEND_FLOW                       rtl8812_suspend_flow
+#define RTL8812_NIC_RESUME_FLOW                                rtl8812_resume_flow
+#define RTL8812_NIC_PDN_FLOW                                   rtl8812_hwpdn_flow
+#define RTL8812_NIC_LPS_ENTER_FLOW                     rtl8812_enter_lps_flow
+#define RTL8812_NIC_LPS_LEAVE_FLOW                     rtl8812_leave_lps_flow
+
+/* RTL8821 Power Configuration CMDs for PCIe interface */
+#define RTL8821A_NIC_PWR_ON_FLOW                       rtl8821A_power_on_flow
+#define RTL8821A_NIC_RF_OFF_FLOW                       rtl8821A_radio_off_flow
+#define RTL8821A_NIC_DISABLE_FLOW                      rtl8821A_card_disable_flow
+#define RTL8821A_NIC_ENABLE_FLOW                       rtl8821A_card_enable_flow
+#define RTL8821A_NIC_SUSPEND_FLOW                      rtl8821A_suspend_flow
+#define RTL8821A_NIC_RESUME_FLOW                       rtl8821A_resume_flow
+#define RTL8821A_NIC_PDN_FLOW                          rtl8821A_hwpdn_flow
+#define RTL8821A_NIC_LPS_ENTER_FLOW                    rtl8821A_enter_lps_flow
+#define RTL8821A_NIC_LPS_LEAVE_FLOW                    rtl8821A_leave_lps_flow
+
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/pwrseqcmd.c b/drivers/staging/rtl8821ae/rtl8821ae/pwrseqcmd.c
new file mode 100644 (file)
index 0000000..710bc01
--- /dev/null
@@ -0,0 +1,140 @@
+/******************************************************************************
+ *
+ * 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 "pwrseq.h"
+
+
+/*
+*      Description:
+*              This routine deal with the Power Configuration CMDs
+*               parsing for RTL8723/RTL8188E Series IC.
+*      Assumption:
+*              We should follow specific format which was released from HW SD.
+*
+*      2011.07.07, added by Roger.
+*/
+bool rtl_hal_pwrseqcmdparsing (struct rtl_priv* rtlpriv, u8 cut_version,
+                                                                               u8 fab_version, u8 interface_type,
+                                                                               struct wlan_pwr_cfg     pwrcfgcmd[])
+
+{
+       struct wlan_pwr_cfg pwr_cfg_cmd = {0};
+       bool polling_bit = false;
+       u32 ary_idx=0;
+       u8 value = 0;
+       u32 offset = 0;
+       u32 polling_count = 0;
+       u32 max_polling_cnt = 5000;
+
+       do {
+               pwr_cfg_cmd = pwrcfgcmd[ary_idx];
+               RT_TRACE(COMP_INIT, DBG_TRACE,
+                       ("rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), fab_msk(%#x),"
+                       "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n",
+                       GET_PWR_CFG_OFFSET(pwr_cfg_cmd), GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd),
+                       GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd), GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd),
+                       GET_PWR_CFG_BASE(pwr_cfg_cmd), GET_PWR_CFG_CMD(pwr_cfg_cmd),
+                       GET_PWR_CFG_MASK(pwr_cfg_cmd), GET_PWR_CFG_VALUE(pwr_cfg_cmd)));
+
+               if ((GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd)&fab_version) &&
+                       (GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd)&cut_version) &&
+                       (GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd)&interface_type)) {
+                       switch (GET_PWR_CFG_CMD(pwr_cfg_cmd)) {
+                       case PWR_CMD_READ:
+                               RT_TRACE(COMP_INIT, DBG_TRACE,
+                                       ("rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"));
+                               break;
+
+                       case PWR_CMD_WRITE: {
+                               RT_TRACE(COMP_INIT, DBG_TRACE,
+                                       ("rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n"));
+                               offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd);
+
+                                       /*Read the value from system register*/
+                                       value = rtl_read_byte(rtlpriv, offset);
+                                       value = value & (~(GET_PWR_CFG_MASK(pwr_cfg_cmd)));
+                                       value = value | (GET_PWR_CFG_VALUE(pwr_cfg_cmd)
+                                                       & GET_PWR_CFG_MASK(pwr_cfg_cmd));
+
+                                       /*Write the value back to sytem register*/
+                                       rtl_write_byte(rtlpriv, offset, value);
+                               }
+                               break;
+
+                       case PWR_CMD_POLLING:
+                               RT_TRACE(COMP_INIT, DBG_TRACE,
+                                       ("rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"));
+                               polling_bit = false;
+                               offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd);
+
+                               do {
+                                       value = rtl_read_byte(rtlpriv, offset);
+
+                                       value = value & GET_PWR_CFG_MASK(pwr_cfg_cmd);
+                                       if (value == (GET_PWR_CFG_VALUE(pwr_cfg_cmd)
+                                                       & GET_PWR_CFG_MASK(pwr_cfg_cmd)))
+                                               polling_bit=true;
+                                       else
+                                               udelay(10);
+
+                                       if (polling_count++ > max_polling_cnt) {
+                                               return false;
+                                       }
+                               } while (!polling_bit);
+
+                               break;
+
+                       case PWR_CMD_DELAY:
+                               RT_TRACE(COMP_INIT, DBG_TRACE,
+                                       ("rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n"));
+                               if (GET_PWR_CFG_VALUE(pwr_cfg_cmd) == PWRSEQ_DELAY_US)
+                                       udelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd));
+                               else
+                                       mdelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd));
+                               break;
+
+                       case PWR_CMD_END:
+                               RT_TRACE(COMP_INIT, DBG_TRACE,
+                                       ("rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n"));
+                               return true;
+                               break;
+
+                       default:
+                               RT_ASSERT(false,
+                                       ("rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n"));
+                               break;
+                       }
+
+               }
+
+               ary_idx++;
+       } while (1);
+
+       return true;
+}
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/pwrseqcmd.h b/drivers/staging/rtl8821ae/rtl8821ae/pwrseqcmd.h
new file mode 100644 (file)
index 0000000..571e7e5
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef __RTL8821AE_PWRSEQCMD_H__
+#define __RTL8821AE_PWRSEQCMD_H__
+
+#include "../wifi.h"
+/*---------------------------------------------*/
+/*The value of cmd: 4 bits */
+/*---------------------------------------------*/
+#define        PWR_CMD_READ            0x00
+#define        PWR_CMD_WRITE   0x01
+#define        PWR_CMD_POLLING 0x02
+#define        PWR_CMD_DELAY   0x03
+#define        PWR_CMD_END             0x04
+
+/* define the base address of each block */
+#define        PWR_BASEADDR_MAC        0x00
+#define        PWR_BASEADDR_USB        0x01
+#define        PWR_BASEADDR_PCIE       0x02
+#define        PWR_BASEADDR_SDIO       0x03
+
+#define        PWR_INTF_SDIO_MSK       BIT(0)
+#define        PWR_INTF_USB_MSK        BIT(1)
+#define        PWR_INTF_PCI_MSK        BIT(2)
+#define        PWR_INTF_ALL_MSK        (BIT(0)|BIT(1)|BIT(2)|BIT(3))
+
+#define        PWR_FAB_TSMC_MSK        BIT(0)
+#define        PWR_FAB_UMC_MSK         BIT(1)
+#define        PWR_FAB_ALL_MSK         (BIT(0)|BIT(1)|BIT(2)|BIT(3))
+
+#define        PWR_CUT_TESTCHIP_MSK    BIT(0)
+#define        PWR_CUT_A_MSK           BIT(1)
+#define        PWR_CUT_B_MSK           BIT(2)
+#define        PWR_CUT_C_MSK           BIT(3)
+#define        PWR_CUT_D_MSK           BIT(4)
+#define        PWR_CUT_E_MSK           BIT(5)
+#define        PWR_CUT_F_MSK           BIT(6)
+#define        PWR_CUT_G_MSK           BIT(7)
+#define        PWR_CUT_ALL_MSK         0xFF
+
+
+enum pwrseq_delay_unit {
+   PWRSEQ_DELAY_US,
+   PWRSEQ_DELAY_MS,
+};
+
+struct wlan_pwr_cfg {
+       u16 offset;
+       u8 cut_msk;
+       u8 fab_msk:4;
+       u8 interface_msk:4;
+       u8 base:4;
+       u8 cmd:4;
+       u8 msk;
+       u8 value;
+
+};
+
+#define        GET_PWR_CFG_OFFSET(__PWR_CMD)   __PWR_CMD.offset
+#define        GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk
+#define        GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk
+#define        GET_PWR_CFG_INTF_MASK(__PWR_CMD)        __PWR_CMD.interface_msk
+#define        GET_PWR_CFG_BASE(__PWR_CMD)     __PWR_CMD.base
+#define        GET_PWR_CFG_CMD(__PWR_CMD)      __PWR_CMD.cmd
+#define        GET_PWR_CFG_MASK(__PWR_CMD)     __PWR_CMD.msk
+#define        GET_PWR_CFG_VALUE(__PWR_CMD)    __PWR_CMD.value
+
+bool rtl_hal_pwrseqcmdparsing(struct rtl_priv * rtlpriv, u8 cut_version,
+                                                                          u8 fab_version, u8 interface_type,
+                                                                          struct wlan_pwr_cfg pwrcfgcmd[]);
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/reg.h b/drivers/staging/rtl8821ae/rtl8821ae/reg.h
new file mode 100644 (file)
index 0000000..09c5f00
--- /dev/null
@@ -0,0 +1,2427 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_REG_H__
+#define __RTL8821AE_REG_H__
+
+#define TXPKT_BUF_SELECT                               0x69
+#define RXPKT_BUF_SELECT                               0xA5
+#define DISABLE_TRXPKT_BUF_ACCESS                      0x0
+
+#define REG_SYS_ISO_CTRL                       0x0000
+#define REG_SYS_FUNC_EN                                0x0002
+#define REG_APS_FSMCO                          0x0004
+#define REG_SYS_CLKR                           0x0008
+#define REG_9346CR                                     0x000A
+#define REG_EE_VPD                                     0x000C
+#define REG_AFE_MISC                           0x0010
+#define REG_SPS0_CTRL                          0x0011
+#define REG_SPS_OCP_CFG                                0x0018
+#define REG_RSV_CTRL                           0x001C
+#define REG_RF_CTRL                                    0x001F
+#define REG_LDOA15_CTRL                                0x0020
+#define REG_LDOV12D_CTRL                       0x0021
+#define REG_LDOHCI12_CTRL                      0x0022
+#define REG_LPLDO_CTRL                         0x0023
+#define REG_AFE_XTAL_CTRL                      0x0024
+#define REG_AFE_LDO_CTRL                       0x0027 /* 1.5v for 8188EE test chip, 1.4v for MP chip */
+#define REG_AFE_PLL_CTRL                       0x0028
+#define REG_MAC_PHY_CTRL                       0x002c
+#define REG_EFUSE_CTRL                         0x0030
+#define REG_EFUSE_TEST                         0x0034
+#define REG_PWR_DATA                           0x0038
+#define REG_CAL_TIMER                          0x003C
+#define REG_ACLK_MON                           0x003E
+#define REG_GPIO_MUXCFG                        0x0040
+#define REG_GPIO_IO_SEL                                0x0042
+#define REG_MAC_PINMUX_CFG             0x0043
+#define REG_GPIO_PIN_CTRL                      0x0044
+#define REG_GPIO_INTM                          0x0048
+#define REG_LEDCFG0                                    0x004C
+#define REG_LEDCFG1                                    0x004D
+#define REG_LEDCFG2                                    0x004E
+#define REG_LEDCFG3                                    0x004F
+#define REG_FSIMR                                      0x0050
+#define REG_FSISR                                      0x0054
+#define REG_HSIMR                                      0x0058
+#define REG_HSISR                                      0x005c
+#define REG_GPIO_PIN_CTRL_2            0x0060
+#define REG_GPIO_IO_SEL_2                      0x0062
+#define REG_MULTI_FUNC_CTRL                    0x0068
+#define REG_GPIO_OUTPUT                        0x006c
+#define REG_OPT_CTRL                   0x0074
+#define REG_AFE_XTAL_CTRL_EXT          0x0078
+#define REG_XCK_OUT_CTRL                       0x007c
+#define REG_MCUFWDL                            0x0080
+#define REG_WOL_EVENT                          0x0081
+#define REG_MCUTSTCFG                          0x0084
+
+
+#define REG_HIMR                                       0x00B0
+#define REG_HISR                                       0x00B4
+#define REG_HIMRE                                      0x00B8
+#define REG_HISRE                                      0x00BC
+
+#define REG_PMC_DBG_CTRL2                      0x00CC
+
+#define REG_EFUSE_ACCESS                       0x00CF
+
+#define REG_BIST_SCAN                          0x00D0
+#define REG_BIST_RPT                           0x00D4
+#define REG_BIST_ROM_RPT                       0x00D8
+#define REG_USB_SIE_INTF                       0x00E0
+#define REG_PCIE_MIO_INTF                      0x00E4
+#define REG_PCIE_MIO_INTD                      0x00E8
+#define REG_HPON_FSM                           0x00EC
+#define REG_SYS_CFG                                    0x00F0
+#define REG_GPIO_OUTSTS                                0x00F4
+#define REG_SYS_CFG1                           0x00FC
+#define REG_ROM_VERSION                                0x00FD
+
+#define REG_CR                                         0x0100
+#define REG_PBP                                                0x0104
+#define REG_PKT_BUFF_ACCESS_CTRL                       0x0106
+#define REG_TRXDMA_CTRL                                0x010C
+#define REG_TRXFF_BNDY                         0x0114
+#define REG_TRXFF_STATUS                       0x0118
+#define REG_RXFF_PTR                           0x011C
+
+#define REG_CPWM                                       0x012F
+#define REG_FWIMR                                      0x0130
+#define REG_FWISR                                      0x0134
+#define REG_PKTBUF_DBG_CTRL                    0x0140
+#define REG_PKTBUF_DBG_DATA_L          0x0144
+#define REG_PKTBUF_DBG_DATA_H          0x0148
+#define REG_RXPKTBUF_CTRL                              (REG_PKTBUF_DBG_CTRL+2)
+
+#define REG_TC0_CTRL                           0x0150
+#define REG_TC1_CTRL                           0x0154
+#define REG_TC2_CTRL                           0x0158
+#define REG_TC3_CTRL                           0x015C
+#define REG_TC4_CTRL                           0x0160
+#define REG_TCUNIT_BASE                                0x0164
+#define REG_MBIST_START                                0x0174
+#define REG_MBIST_DONE                         0x0178
+#define REG_MBIST_FAIL                         0x017C
+#define REG_32K_CTRL                                   0x0194
+#define REG_C2HEVT_MSG_NORMAL          0x01A0
+#define REG_C2HEVT_CLEAR                       0x01AF
+#define REG_C2HEVT_MSG_TEST                    0x01B8
+#define REG_MCUTST_1                           0x01c0
+#define REG_FMETHR                                     0x01C8
+#define REG_HMETFR                                     0x01CC
+#define REG_HMEBOX_0                           0x01D0
+#define REG_HMEBOX_1                           0x01D4
+#define REG_HMEBOX_2                           0x01D8
+#define REG_HMEBOX_3                           0x01DC
+
+#define REG_LLT_INIT                           0x01E0
+#define REG_BB_ACCEESS_CTRL                    0x01E8
+#define REG_BB_ACCESS_DATA                     0x01EC
+
+#define REG_HMEBOX_EXT_0                       0x01F0
+#define REG_HMEBOX_EXT_1                       0x01F4
+#define REG_HMEBOX_EXT_2                       0x01F8
+#define REG_HMEBOX_EXT_3                       0x01FC
+
+#define REG_RQPN                                       0x0200
+#define REG_FIFOPAGE                           0x0204
+#define REG_TDECTRL                                    0x0208
+#define REG_TXDMA_OFFSET_CHK           0x020C
+#define REG_TXDMA_STATUS                       0x0210
+#define REG_RQPN_NPQ                           0x0214
+
+#define REG_RXDMA_AGG_PG_TH            0x0280
+#define REG_FW_UPD_RDPTR                       0x0284 /* FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 */
+#define REG_RXDMA_CONTROL                      0x0286 /* Control the RX DMA.*/
+#define REG_RXPKT_NUM                          0x0287 /* The number of packets in RXPKTBUF.    */
+
+#define        REG_PCIE_CTRL_REG                       0x0300
+#define        REG_INT_MIG                                     0x0304
+#define        REG_BCNQ_DESA                           0x0308
+#define        REG_HQ_DESA                                     0x0310
+#define        REG_MGQ_DESA                            0x0318
+#define        REG_VOQ_DESA                            0x0320
+#define        REG_VIQ_DESA                            0x0328
+#define        REG_BEQ_DESA                            0x0330
+#define        REG_BKQ_DESA                            0x0338
+#define        REG_RX_DESA                                     0x0340
+
+#define        REG_DBI_WDATA                           0x0348
+#define        REG_DBI_RDATA                           0x034C
+#define        REG_DBI_ADDR                            0x0350
+#define        REG_DBI_FLAG                            0x0352
+#define        REG_MDIO_WDATA                          0x0354
+#define        REG_MDIO_RDATA                          0x0356
+#define        REG_MDIO_CTL                            0x0358
+#define        REG_DBG_SEL                                     0x0360
+#define        REG_PCIE_HRPWM                          0x0361
+#define        REG_PCIE_HCPWM                          0x0363
+#define        REG_UART_CTRL                           0x0364
+#define        REG_WATCH_DOG                           0x0368
+#define        REG_UART_TX_DESA                        0x0370
+#define        REG_UART_RX_DESA                        0x0378
+
+
+#define        REG_HDAQ_DESA_NODEF                     0x0000
+#define        REG_CMDQ_DESA_NODEF                     0x0000
+
+#define REG_VOQ_INFORMATION                    0x0400
+#define REG_VIQ_INFORMATION                    0x0404
+#define REG_BEQ_INFORMATION                    0x0408
+#define REG_BKQ_INFORMATION                    0x040C
+#define REG_MGQ_INFORMATION                    0x0410
+#define REG_HGQ_INFORMATION                    0x0414
+#define REG_BCNQ_INFORMATION                   0x0418
+#define REG_TXPKT_EMPTY                                0x041A
+
+
+#define REG_CPU_MGQ_INFORMATION                0x041C
+#define REG_FWHW_TXQ_CTRL                      0x0420
+#define REG_HWSEQ_CTRL                         0x0423
+#define REG_TXPKTBUF_BCNQ_BDNY         0x0424
+#define REG_TXPKTBUF_MGQ_BDNY          0x0425
+#define REG_MULTI_BCNQ_EN                      0x0426
+#define REG_MULTI_BCNQ_OFFSET          0x0427
+#define REG_SPEC_SIFS                          0x0428
+#define REG_RL                                         0x042A
+#define REG_DARFRC                                     0x0430
+#define REG_RARFRC                                     0x0438
+#define REG_RRSR                                       0x0440
+#define REG_ARFR0                                      0x0444
+#define REG_ARFR1                                      0x044C
+#define REG_CCK_CHECK                          0x0454
+#define REG_AMPDU_MAX_TIME                     0x0456
+#define REG_AGGLEN_LMT                         0x0458
+#define REG_AMPDU_MIN_SPACE                    0x045C
+#define REG_TXPKTBUF_WMAC_LBK_BF_HD    0x045D
+#define REG_FAST_EDCA_CTRL                     0x0460
+#define REG_RD_RESP_PKT_TH                     0x0463
+#define REG_INIRTS_RATE_SEL                    0x0480
+#define REG_INIDATA_RATE_SEL           0x0484
+#define REG_ARFR2                                      0x048C
+#define REG_ARFR3                                      0x0494
+#define REG_POWER_STATUS                       0x04A4
+#define REG_POWER_STAGE1                       0x04B4
+#define REG_POWER_STAGE2                       0x04B8
+#define REG_PKT_LIFE_TIME                      0x04C0
+#define REG_STBC_SETTING                       0x04C4
+#define REG_HT_SINGLE_AMPDU                    0x04C7
+#define REG_PROT_MODE_CTRL                     0x04C8
+#define REG_MAX_AGGR_NUM                       0x04CA
+#define REG_BAR_MODE_CTRL                      0x04CC
+#define REG_RA_TRY_RATE_AGG_LMT                0x04CF
+#define REG_EARLY_MODE_CONTROL                 0x04D0
+#define REG_NQOS_SEQ                           0x04DC
+#define REG_QOS_SEQ                                    0x04DE
+#define REG_NEED_CPU_HANDLE                    0x04E0
+#define REG_PKT_LOSE_RPT                       0x04E1
+#define REG_PTCL_ERR_STATUS                    0x04E2
+#define REG_TX_RPT_CTRL                                0x04EC
+#define REG_TX_RPT_TIME                                0x04F0
+#define REG_DUMMY                                      0x04FC
+
+#define REG_EDCA_VO_PARAM                      0x0500
+#define REG_EDCA_VI_PARAM                      0x0504
+#define REG_EDCA_BE_PARAM                      0x0508
+#define REG_EDCA_BK_PARAM                      0x050C
+#define REG_BCNTCFG                                    0x0510
+#define REG_PIFS                                       0x0512
+#define REG_RDG_PIFS                           0x0513
+#define REG_SIFS_CTX                           0x0514
+#define REG_SIFS_TRX                           0x0516
+#define REG_AGGR_BREAK_TIME                    0x051A
+#define REG_SLOT                                       0x051B
+#define REG_TX_PTCL_CTRL                       0x0520
+#define REG_TXPAUSE                                    0x0522
+#define REG_DIS_TXREQ_CLR                      0x0523
+#define REG_RD_CTRL                                    0x0524
+#define REG_TBTT_PROHIBIT                      0x0540
+#define REG_RD_NAV_NXT                         0x0544
+#define REG_NAV_PROT_LEN                       0x0546
+#define REG_BCN_CTRL                           0x0550
+#define REG_USTIME_TSF                         0x0551
+#define REG_MBID_NUM                           0x0552
+#define REG_DUAL_TSF_RST                       0x0553
+#define REG_BCN_INTERVAL                       0x0554
+#define REG_MBSSID_BCN_SPACE           0x0554
+#define REG_DRVERLYINT                         0x0558
+#define REG_BCNDMATIM                          0x0559
+#define REG_ATIMWND                                    0x055A
+#define REG_BCN_MAX_ERR                                0x055D
+#define REG_RXTSF_OFFSET_CCK           0x055E
+#define REG_RXTSF_OFFSET_OFDM          0x055F
+#define REG_TSFTR                                      0x0560
+#define REG_INIT_TSFTR                         0x0564
+#define REG_SECONDARY_CCA_CTRL         0x0577
+#define REG_PSTIMER                                    0x0580
+#define REG_TIMER0                                     0x0584
+#define REG_TIMER1                                     0x0588
+#define REG_ACMHWCTRL                          0x05C0
+#define REG_ACMRSTCTRL                         0x05C1
+#define REG_ACMAVG                                     0x05C2
+#define REG_VO_ADMTIME                         0x05C4
+#define REG_VI_ADMTIME                         0x05C6
+#define REG_BE_ADMTIME                         0x05C8
+#define REG_EDCA_RANDOM_GEN                    0x05CC
+#define REG_NOA_DESC_SEL                       0x05CF
+#define REG_NOA_DESC_DURATION          0x05E0
+#define REG_NOA_DESC_INTERVAL          0x05E4
+#define REG_NOA_DESC_START                     0x05E8
+#define REG_NOA_DESC_COUNT                     0x05EC
+#define REG_SCH_TX_CMD                         0x05F8
+
+#define REG_APSD_CTRL                          0x0600
+#define REG_BWOPMODE                           0x0603
+#define REG_TCR                                                0x0604
+#define REG_RCR                                                0x0608
+#define REG_RX_PKT_LIMIT                       0x060C
+#define REG_RX_DLK_TIME                                0x060D
+#define REG_RX_DRVINFO_SZ                      0x060F
+
+#define REG_MACID                                      0x0610
+#define REG_BSSID                                      0x0618
+#define REG_MAR                                                0x0620
+#define REG_MBIDCAMCFG                         0x0628
+
+#define REG_USTIME_EDCA                                0x0638
+#define REG_MAC_SPEC_SIFS                      0x063A
+#define REG_RESP_SIFS_CCK                      0x063C
+#define REG_RESP_SIFS_OFDM                     0x063E
+#define REG_ACKTO                                      0x0640
+#define REG_CTS2TO                                     0x0641
+#define REG_EIFS                                       0x0642
+
+#define REG_NAV_CTRL                           0x0650
+#define REG_NAV_UPPER                          0x0652
+#define REG_BACAMCMD                           0x0654
+#define REG_BACAMCONTENT                       0x0658
+#define REG_LBDLY                                      0x0660
+#define REG_FWDLY                                      0x0661
+#define REG_RXERR_RPT                          0x0664
+#define REG_TRXPTCL_CTL                                0x0668
+
+#define REG_CAMCMD                                     0x0670
+#define REG_CAMWRITE                           0x0674
+#define REG_CAMREAD                                    0x0678
+#define REG_CAMDBG                                     0x067C
+#define REG_SECCFG                                     0x0680
+
+#define REG_WOW_CTRL                           0x0690
+#define REG_PSSTATUS                           0x0691
+#define REG_PS_RX_INFO                         0x0692
+#define REG_UAPSD_TID                          0x0693
+#define REG_LPNAV_CTRL                         0x0694
+#define REG_WKFMCAM_NUM                                0x0698
+#define REG_WKFMCAM_RWD                                0x069C
+#define REG_RXFLTMAP0                          0x06A0
+#define REG_RXFLTMAP1                          0x06A2
+#define REG_RXFLTMAP2                          0x06A4
+#define REG_BCN_PSR_RPT                                0x06A8
+#define REG_CALB32K_CTRL                       0x06AC
+#define REG_PKT_MON_CTRL                       0x06B4
+#define REG_BT_COEX_TABLE                      0x06C0
+#define REG_WMAC_RESP_TXINFO           0x06D8
+
+#define REG_USB_INFO                           0xFE17
+#define REG_USB_SPECIAL_OPTION         0xFE55
+#define REG_USB_DMA_AGG_TO                     0xFE5B
+#define REG_USB_AGG_TO                         0xFE5C
+#define REG_USB_AGG_TH                         0xFE5D
+
+#define REG_TEST_USB_TXQS                      0xFE48
+#define REG_TEST_SIE_VID                       0xFE60
+#define REG_TEST_SIE_PID                       0xFE62
+#define REG_TEST_SIE_OPTIONAL          0xFE64
+#define REG_TEST_SIE_CHIRP_K           0xFE65
+#define REG_TEST_SIE_PHY                       0xFE66
+#define REG_TEST_SIE_MAC_ADDR          0xFE70
+#define REG_TEST_SIE_STRING                    0xFE80
+
+#define REG_NORMAL_SIE_VID                     0xFE60
+#define REG_NORMAL_SIE_PID                     0xFE62
+#define REG_NORMAL_SIE_OPTIONAL                0xFE64
+#define REG_NORMAL_SIE_EP                      0xFE65
+#define REG_NORMAL_SIE_PHY                     0xFE68
+#define REG_NORMAL_SIE_MAC_ADDR                0xFE70
+#define REG_NORMAL_SIE_STRING          0xFE80
+
+#define        CR9346                          REG_9346CR
+#define        MSR                             (REG_CR + 2)
+#define        ISR                             REG_HISR
+#define        TSFR                            REG_TSFTR
+
+#define        MACIDR0                         REG_MACID
+#define        MACIDR4                         (REG_MACID + 4)
+
+#define PBP                            REG_PBP
+
+#define        IDR0                            MACIDR0
+#define        IDR4                            MACIDR4
+
+#define        UNUSED_REGISTER                 0x1BF
+#define        DCAM                            UNUSED_REGISTER
+#define        PSR                             UNUSED_REGISTER
+#define BBADDR                         UNUSED_REGISTER
+#define        PHYDATAR                        UNUSED_REGISTER
+
+#define        INVALID_BBRF_VALUE              0x12345678
+
+#define        MAX_MSS_DENSITY_2T              0x13
+#define        MAX_MSS_DENSITY_1T              0x0A
+
+#define        CMDEEPROM_EN                    BIT(5)
+#define        CMDEEPROM_SEL                   BIT(4)
+#define        CMD9346CR_9356SEL               BIT(4)
+#define        AUTOLOAD_EEPROM                 (CMDEEPROM_EN|CMDEEPROM_SEL)
+#define        AUTOLOAD_EFUSE                  CMDEEPROM_EN
+
+#define        GPIOSEL_GPIO                    0
+#define        GPIOSEL_ENBT                    BIT(5)
+
+#define        GPIO_IN                         REG_GPIO_PIN_CTRL
+#define        GPIO_OUT                        (REG_GPIO_PIN_CTRL+1)
+#define        GPIO_IO_SEL                     (REG_GPIO_PIN_CTRL+2)
+#define        GPIO_MOD                        (REG_GPIO_PIN_CTRL+3)
+
+/*      8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */
+#define        HSIMR_GPIO12_0_INT_EN                   BIT(0)
+#define        HSIMR_SPS_OCP_INT_EN                    BIT(5)
+#define        HSIMR_RON_INT_EN                        BIT(6)
+#define        HSIMR_PDN_INT_EN                        BIT(7)
+#define        HSIMR_GPIO9_INT_EN                      BIT(25)
+
+
+/*
+*       8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte)
+*/
+#define        HSISR_GPIO12_0_INT                      BIT(0)
+#define        HSISR_SPS_OCP_INT                       BIT(5)
+#define        HSISR_RON_INT_EN                        BIT(6)
+#define        HSISR_PDNINT                            BIT(7)
+#define        HSISR_GPIO9_INT                         BIT(25)
+
+#define        MSR_NOLINK                                      0x00
+#define        MSR_ADHOC                                       0x01
+#define        MSR_INFRA                                       0x02
+#define        MSR_AP                                          0x03
+
+#define        RRSR_RSC_OFFSET                         21
+#define        RRSR_SHORT_OFFSET                       23
+#define        RRSR_RSC_BW_40M                         0x600000
+#define        RRSR_RSC_UPSUBCHNL                      0x400000
+#define        RRSR_RSC_LOWSUBCHNL                     0x200000
+#define        RRSR_SHORT                                      0x800000
+#define        RRSR_1M                                         BIT(0)
+#define        RRSR_2M                                         BIT(1)
+#define        RRSR_5_5M                                       BIT(2)
+#define        RRSR_11M                                        BIT(3)
+#define        RRSR_6M                                         BIT(4)
+#define        RRSR_9M                                         BIT(5)
+#define        RRSR_12M                                        BIT(6)
+#define        RRSR_18M                                        BIT(7)
+#define        RRSR_24M                                        BIT(8)
+#define        RRSR_36M                                        BIT(9)
+#define        RRSR_48M                                        BIT(10)
+#define        RRSR_54M                                        BIT(11)
+#define        RRSR_MCS0                                       BIT(12)
+#define        RRSR_MCS1                                       BIT(13)
+#define        RRSR_MCS2                                       BIT(14)
+#define        RRSR_MCS3                                       BIT(15)
+#define        RRSR_MCS4                                       BIT(16)
+#define        RRSR_MCS5                                       BIT(17)
+#define        RRSR_MCS6                                       BIT(18)
+#define        RRSR_MCS7                                       BIT(19)
+#define        BRSR_ACKSHORTPMB                        BIT(23)
+
+#define        RATR_1M                                         0x00000001
+#define        RATR_2M                                         0x00000002
+#define        RATR_55M                                        0x00000004
+#define        RATR_11M                                        0x00000008
+#define        RATR_6M                                         0x00000010
+#define        RATR_9M                                         0x00000020
+#define        RATR_12M                                        0x00000040
+#define        RATR_18M                                        0x00000080
+#define        RATR_24M                                        0x00000100
+#define        RATR_36M                                        0x00000200
+#define        RATR_48M                                        0x00000400
+#define        RATR_54M                                        0x00000800
+#define        RATR_MCS0                                       0x00001000
+#define        RATR_MCS1                                       0x00002000
+#define        RATR_MCS2                                       0x00004000
+#define        RATR_MCS3                                       0x00008000
+#define        RATR_MCS4                                       0x00010000
+#define        RATR_MCS5                                       0x00020000
+#define        RATR_MCS6                                       0x00040000
+#define        RATR_MCS7                                       0x00080000
+#define        RATR_MCS8                                       0x00100000
+#define        RATR_MCS9                                       0x00200000
+#define        RATR_MCS10                                      0x00400000
+#define        RATR_MCS11                                      0x00800000
+#define        RATR_MCS12                                      0x01000000
+#define        RATR_MCS13                                      0x02000000
+#define        RATR_MCS14                                      0x04000000
+#define        RATR_MCS15                                      0x08000000
+
+#define RATE_1M                                                BIT(0)
+#define RATE_2M                                                BIT(1)
+#define RATE_5_5M                                      BIT(2)
+#define RATE_11M                                       BIT(3)
+#define RATE_6M                                                BIT(4)
+#define RATE_9M                                                BIT(5)
+#define RATE_12M                                       BIT(6)
+#define RATE_18M                                       BIT(7)
+#define RATE_24M                                       BIT(8)
+#define RATE_36M                                       BIT(9)
+#define RATE_48M                                       BIT(10)
+#define RATE_54M                                       BIT(11)
+#define RATE_MCS0                                      BIT(12)
+#define RATE_MCS1                                      BIT(13)
+#define RATE_MCS2                                      BIT(14)
+#define RATE_MCS3                                      BIT(15)
+#define RATE_MCS4                                      BIT(16)
+#define RATE_MCS5                                      BIT(17)
+#define RATE_MCS6                                      BIT(18)
+#define RATE_MCS7                                      BIT(19)
+#define RATE_MCS8                                      BIT(20)
+#define RATE_MCS9                                      BIT(21)
+#define RATE_MCS10                                     BIT(22)
+#define RATE_MCS11                                     BIT(23)
+#define RATE_MCS12                                     BIT(24)
+#define RATE_MCS13                                     BIT(25)
+#define RATE_MCS14                                     BIT(26)
+#define RATE_MCS15                                     BIT(27)
+
+#define        RATE_ALL_CCK            (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
+#define        RATE_ALL_OFDM_AG        (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\
+                                                       RATR_24M| RATR_36M | RATR_48M | RATR_54M)
+#define        RATE_ALL_OFDM_1SS       (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\
+                                                       RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\
+                                                       RATR_MCS6 | RATR_MCS7)
+#define        RATE_ALL_OFDM_2SS       (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\
+                                                       RATR_MCS11| RATR_MCS12 | RATR_MCS13 |\
+                                                       RATR_MCS14 | RATR_MCS15)
+
+#define        BW_OPMODE_20MHZ                         BIT(2)
+#define        BW_OPMODE_5G                            BIT(1)
+#define        BW_OPMODE_11J                           BIT(0)
+
+#define        CAM_VALID                                       BIT(15)
+#define        CAM_NOTVALID                            0x0000
+#define        CAM_USEDK                                       BIT(5)
+
+#define        CAM_NONE                                        0x0
+#define        CAM_WEP40                                       0x01
+#define        CAM_TKIP                                        0x02
+#define        CAM_AES                                         0x04
+#define        CAM_WEP104                                      0x05
+
+#define        TOTAL_CAM_ENTRY                         32
+#define        HALF_CAM_ENTRY                          16
+
+#define        CAM_WRITE                                       BIT(16)
+#define        CAM_READ                                        0x00000000
+#define        CAM_POLLINIG                            BIT(31)
+
+#define        SCR_USEDK                                       0x01
+#define        SCR_TXSEC_ENABLE                        0x02
+#define        SCR_RXSEC_ENABLE                        0x04
+
+#define        WOW_PMEN                                        BIT(0)
+#define        WOW_WOMEN                                       BIT(1)
+#define        WOW_MAGIC                                       BIT(2)
+#define        WOW_UWF                                         BIT(3)
+
+/*********************************************
+*       8188 IMR/ISR bits
+**********************************************/
+#define        IMR_DISABLED                    0x0
+/* IMR DW0(0x0060-0063) Bit 0-31 */
+#define        IMR_TXCCK                               BIT(30)         /* TXRPT interrupt when CCX bit of the packet is set    */
+#define        IMR_PSTIMEOUT                   BIT(29)         /* Power Save Time Out Interrupt */
+#define        IMR_GTINT4                              BIT(28)         /* When GTIMER4 expires, this bit is set to 1   */
+#define        IMR_GTINT3                              BIT(27)         /* When GTIMER3 expires, this bit is set to 1   */
+#define        IMR_TBDER                               BIT(26)         /* Transmit Beacon0 Error                       */
+#define        IMR_TBDOK                               BIT(25)         /* Transmit Beacon0 OK                  */
+#define        IMR_TSF_BIT32_TOGGLE            BIT(24)         /* TSF Timer BIT32 toggle indication interrupt          */
+#define        IMR_BCNDMAINT0                  BIT(20)         /* Beacon DMA Interrupt 0                       */
+#define        IMR_BCNDOK0                             BIT(16)         /* Beacon Queue DMA OK0                 */
+#define        IMR_HSISR_IND_ON_INT            BIT(15)         /* HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1)                */
+#define        IMR_BCNDMAINT_E                 BIT(14)         /* Beacon DMA Interrupt Extension for Win7                      */
+#define        IMR_ATIMEND                             BIT(12)         /* CTWidnow End or ATIM Window End */
+#define        IMR_HISR1_IND_INT                       BIT(11)         /* HISR1 Indicator (HISR1 & HIMR1 is true, this bit is set to 1)*/
+#define        IMR_C2HCMD                              BIT(10)         /* CPU to Host Command INT Status, Write 1 clear        */
+#define        IMR_CPWM2                       BIT(9)                  /* CPU power Mode exchange INT Status, Write 1 clear    */
+#define        IMR_CPWM                                BIT(8)                  /* CPU power Mode exchange INT Status, Write 1 clear    */
+#define        IMR_HIGHDOK                             BIT(7)                  /* High Queue DMA OK    */
+#define        IMR_MGNTDOK                             BIT(6)                  /* Management Queue DMA OK      */
+#define        IMR_BKDOK                               BIT(5)                  /* AC_BK DMA OK         */
+#define        IMR_BEDOK                               BIT(4)          /* AC_BE DMA OK */
+#define        IMR_VIDOK                               BIT(3)                  /* AC_VI DMA OK */
+#define        IMR_VODOK                               BIT(2)                  /* AC_VO DMA OK */
+#define        IMR_RDU                         BIT(1)                  /* Rx Descriptor Unavailable    */
+#define        IMR_ROK                         BIT(0)                  /* Receive DMA OK */
+
+/* IMR DW1(0x00B4-00B7) Bit 0-31 */
+#define        IMR_BCNDMAINT7                  BIT(27)         /* Beacon DMA Interrupt 7       */
+#define        IMR_BCNDMAINT6                  BIT(26)         /* Beacon DMA Interrupt 6               */
+#define        IMR_BCNDMAINT5                  BIT(25)         /* Beacon DMA Interrupt 5               */
+#define        IMR_BCNDMAINT4                  BIT(24)         /* Beacon DMA Interrupt 4               */
+#define        IMR_BCNDMAINT3                  BIT(23)         /* Beacon DMA Interrupt 3               */
+#define        IMR_BCNDMAINT2                  BIT(22)         /* Beacon DMA Interrupt 2               */
+#define        IMR_BCNDMAINT1                  BIT(21)         /* Beacon DMA Interrupt 1               */
+#define        IMR_BCNDOK7                             BIT(20)         /* Beacon Queue DMA OK Interrup 7 */
+#define        IMR_BCNDOK6                             BIT(19)         /* Beacon Queue DMA OK Interrup 6 */
+#define        IMR_BCNDOK5                             BIT(18)         /* Beacon Queue DMA OK Interrup 5 */
+#define        IMR_BCNDOK4                             BIT(17)         /* Beacon Queue DMA OK Interrup 4 */
+#define        IMR_BCNDOK3                             BIT(16)         /* Beacon Queue DMA OK Interrup 3 */
+#define        IMR_BCNDOK2                             BIT(15)         /* Beacon Queue DMA OK Interrup 2 */
+#define        IMR_BCNDOK1                             BIT(14)         /* Beacon Queue DMA OK Interrup 1 */
+#define        IMR_ATIMEND_E           BIT(13)         /* ATIM Window End Extension for Win7 */
+#define        IMR_TXERR                               BIT(11)         /* Tx Error Flag Interrupt Status, write 1 clear. */
+#define        IMR_RXERR                               BIT(10)         /* Rx Error Flag INT Status, Write 1 clear */
+#define        IMR_TXFOVW                              BIT(9)                  /* Transmit FIFO Overflow */
+#define        IMR_RXFOVW                              BIT(8)                  /* Receive FIFO Overflow */
+
+
+#define        HWSET_MAX_SIZE                          512
+#define   EFUSE_MAX_SECTION                    64
+#define   EFUSE_REAL_CONTENT_LEN                       256
+#define        EFUSE_OOB_PROTECT_BYTES         18      /* PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte.*/
+
+
+#define        EEPROM_DEFAULT_TSSI                                     0x0
+#define EEPROM_DEFAULT_TXPOWERDIFF                     0x0
+#define EEPROM_DEFAULT_CRYSTALCAP                      0x5
+#define EEPROM_DEFAULT_BOARDTYPE                       0x02
+#define EEPROM_DEFAULT_TXPOWER                         0x1010
+#define        EEPROM_DEFAULT_HT2T_TXPWR                       0x10
+
+#define        EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF      0x3
+#define        EEPROM_DEFAULT_THERMALMETER                     0x18
+#define        EEPROM_DEFAULT_ANTTXPOWERDIFF           0x0
+#define        EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP      0x5
+#define        EEPROM_DEFAULT_TXPOWERLEVEL                     0x22
+#define        EEPROM_DEFAULT_HT40_2SDIFF                      0x0
+#define EEPROM_DEFAULT_HT20_DIFF                       2
+#define        EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF      0x3
+#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET       0
+#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET       0
+
+#define RF_OPTION1                                                     0x79
+#define RF_OPTION2                                                     0x7A
+#define RF_OPTION3                                                     0x7B
+#define RF_OPTION4                                                     0xC3
+
+#define EEPROM_DEFAULT_PID                                     0x1234
+#define EEPROM_DEFAULT_VID                                     0x5678
+#define EEPROM_DEFAULT_CUSTOMERID                      0xAB
+#define EEPROM_DEFAULT_SUBCUSTOMERID           0xCD
+#define EEPROM_DEFAULT_VERSION                         0
+
+#define        EEPROM_CHANNEL_PLAN_FCC                         0x0
+#define        EEPROM_CHANNEL_PLAN_IC                          0x1
+#define        EEPROM_CHANNEL_PLAN_ETSI                        0x2
+#define        EEPROM_CHANNEL_PLAN_SPAIN                       0x3
+#define        EEPROM_CHANNEL_PLAN_FRANCE                      0x4
+#define        EEPROM_CHANNEL_PLAN_MKK                         0x5
+#define        EEPROM_CHANNEL_PLAN_MKK1                        0x6
+#define        EEPROM_CHANNEL_PLAN_ISRAEL                      0x7
+#define        EEPROM_CHANNEL_PLAN_TELEC                       0x8
+#define        EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN       0x9
+#define        EEPROM_CHANNEL_PLAN_WORLD_WIDE_13       0xA
+#define        EEPROM_CHANNEL_PLAN_NCC                         0xB
+#define        EEPROM_CHANNEL_PLAN_BY_HW_MASK          0x80
+
+#define EEPROM_CID_DEFAULT                                     0x0
+#define EEPROM_CID_TOSHIBA                                     0x4
+#define        EEPROM_CID_CCX                                          0x10
+#define        EEPROM_CID_QMI                                          0x0D
+#define EEPROM_CID_WHQL                                        0xFE
+
+#define        RTL_EEPROM_ID                                   0x8129
+
+#define EEPROM_HPON                                                    0x02
+#define EEPROM_CLK                                                     0x06
+#define EEPROM_TESTR                                           0x08
+
+
+#define EEPROM_TXPOWERCCK                      0x10
+#define        EEPROM_TXPOWERHT40_1S           0x16
+#define EEPROM_TXPOWERHT20DIFF         0x1B
+#define EEPROM_TXPOWER_OFDMDIFF                0x1B
+
+
+
+#define        EEPROM_TX_PWR_INX                               0x10
+
+#define        EEPROM_CHANNELPLAN                                      0xB8
+#define        EEPROM_XTAL_8821AE                                      0xB9
+#define        EEPROM_THERMAL_METER                            0xBA
+#define        EEPROM_IQK_LCK_88E                                      0xBB
+
+#define        EEPROM_RF_BOARD_OPTION                  0xC1
+#define        EEPROM_RF_FEATURE_OPTION_88E            0xC2
+#define        EEPROM_RF_BT_SETTING                            0xC3
+#define        EEPROM_VERSION                                  0xC4
+#define        EEPROM_CUSTOMER_ID                                      0xC5
+#define        EEPROM_RF_ANTENNA_OPT_88E                       0xC9
+
+#define        EEPROM_MAC_ADDR                                 0xD0
+#define EEPROM_VID                                                     0xD6
+#define EEPROM_DID                                                     0xD8
+#define EEPROM_SVID                                                    0xDA
+#define EEPROM_SMID                                            0xDC
+
+#define        STOPBECON                                       BIT(6)
+#define        STOPHIGHT                                       BIT(5)
+#define        STOPMGT                                         BIT(4)
+#define        STOPVO                                          BIT(3)
+#define        STOPVI                                          BIT(2)
+#define        STOPBE                                          BIT(1)
+#define        STOPBK                                          BIT(0)
+
+#define        RCR_APPFCS                                      BIT(31)
+#define        RCR_APP_MIC                                     BIT(30)
+#define        RCR_APP_ICV                                     BIT(29)
+#define        RCR_APP_PHYST_RXFF                      BIT(28)
+#define        RCR_APP_BA_SSN                          BIT(27)
+#define        RCR_NONQOS_VHT                          BIT(26)
+#define        RCR_ENMBID                                      BIT(24)
+#define        RCR_LSIGEN                                      BIT(23)
+#define        RCR_MFBEN                                       BIT(22)
+#define        RCR_HTC_LOC_CTRL                        BIT(14)
+#define        RCR_AMF                                         BIT(13)
+#define        RCR_ACF                                         BIT(12)
+#define        RCR_ADF                                         BIT(11)
+#define        RCR_AICV                                        BIT(9)
+#define        RCR_ACRC32                                      BIT(8)
+#define        RCR_CBSSID_BCN                          BIT(7)
+#define        RCR_CBSSID_DATA                         BIT(6)
+#define        RCR_CBSSID                                      RCR_CBSSID_DATA
+#define        RCR_APWRMGT                                     BIT(5)
+#define        RCR_ADD3                                        BIT(4)
+#define        RCR_AB                                          BIT(3)
+#define        RCR_AM                                          BIT(2)
+#define        RCR_APM                                         BIT(1)
+#define        RCR_AAP                                         BIT(0)
+#define        RCR_MXDMA_OFFSET                        8
+#define        RCR_FIFO_OFFSET                         13
+
+#define RSV_CTRL                                       0x001C
+#define RD_CTRL                                                0x0524
+
+#define REG_USB_INFO                           0xFE17
+#define REG_USB_SPECIAL_OPTION         0xFE55
+#define REG_USB_DMA_AGG_TO                     0xFE5B
+#define REG_USB_AGG_TO                         0xFE5C
+#define REG_USB_AGG_TH                         0xFE5D
+
+#define REG_USB_VID                                    0xFE60
+#define REG_USB_PID                                    0xFE62
+#define REG_USB_OPTIONAL                       0xFE64
+#define REG_USB_CHIRP_K                                0xFE65
+#define REG_USB_PHY                                    0xFE66
+#define REG_USB_MAC_ADDR                       0xFE70
+#define REG_USB_HRPWM                          0xFE58
+#define REG_USB_HCPWM                          0xFE57
+
+#define SW18_FPWM                                      BIT(3)
+
+#define ISO_MD2PP                                      BIT(0)
+#define ISO_UA2USB                                     BIT(1)
+#define ISO_UD2CORE                                    BIT(2)
+#define ISO_PA2PCIE                                    BIT(3)
+#define ISO_PD2CORE                                    BIT(4)
+#define ISO_IP2MAC                                     BIT(5)
+#define ISO_DIOP                                       BIT(6)
+#define ISO_DIOE                                       BIT(7)
+#define ISO_EB2CORE                                    BIT(8)
+#define ISO_DIOR                                       BIT(9)
+
+#define PWC_EV25V                                      BIT(14)
+#define PWC_EV12V                                      BIT(15)
+
+#define FEN_BBRSTB                                     BIT(0)
+#define FEN_BB_GLB_RSTN                                BIT(1)
+#define FEN_USBA                                       BIT(2)
+#define FEN_UPLL                                       BIT(3)
+#define FEN_USBD                                       BIT(4)
+#define FEN_DIO_PCIE                           BIT(5)
+#define FEN_PCIEA                                      BIT(6)
+#define FEN_PPLL                                       BIT(7)
+#define FEN_PCIED                                      BIT(8)
+#define FEN_DIOE                                       BIT(9)
+#define FEN_CPUEN                                      BIT(10)
+#define FEN_DCORE                                      BIT(11)
+#define FEN_ELDR                                       BIT(12)
+#define FEN_DIO_RF                                     BIT(13)
+#define FEN_HWPDN                                      BIT(14)
+#define FEN_MREGEN                                     BIT(15)
+
+#define PFM_LDALL                                      BIT(0)
+#define PFM_ALDN                                       BIT(1)
+#define PFM_LDKP                                       BIT(2)
+#define PFM_WOWL                                       BIT(3)
+#define EnPDN                                          BIT(4)
+#define PDN_PL                                         BIT(5)
+#define APFM_ONMAC                                     BIT(8)
+#define APFM_OFF                                       BIT(9)
+#define APFM_RSM                                       BIT(10)
+#define AFSM_HSUS                                      BIT(11)
+#define AFSM_PCIE                                      BIT(12)
+#define APDM_MAC                                       BIT(13)
+#define APDM_HOST                                      BIT(14)
+#define APDM_HPDN                                      BIT(15)
+#define RDY_MACON                                      BIT(16)
+#define SUS_HOST                                       BIT(17)
+#define ROP_ALD                                                BIT(20)
+#define ROP_PWR                                                BIT(21)
+#define ROP_SPS                                                BIT(22)
+#define SOP_MRST                                       BIT(25)
+#define SOP_FUSE                                       BIT(26)
+#define SOP_ABG                                                BIT(27)
+#define SOP_AMB                                                BIT(28)
+#define SOP_RCK                                                BIT(29)
+#define SOP_A8M                                                BIT(30)
+#define XOP_BTCK                                       BIT(31)
+
+#define ANAD16V_EN                                     BIT(0)
+#define ANA8M                                          BIT(1)
+#define MACSLP                                         BIT(4)
+#define LOADER_CLK_EN                          BIT(5)
+#define _80M_SSC_DIS                           BIT(7)
+#define _80M_SSC_EN_HO                         BIT(8)
+#define PHY_SSC_RSTB                           BIT(9)
+#define SEC_CLK_EN                                     BIT(10)
+#define MAC_CLK_EN                                     BIT(11)
+#define SYS_CLK_EN                                     BIT(12)
+#define RING_CLK_EN                                    BIT(13)
+
+#define        BOOT_FROM_EEPROM                        BIT(4)
+#define        EEPROM_EN                                       BIT(5)
+
+#define AFE_BGEN                                       BIT(0)
+#define AFE_MBEN                                       BIT(1)
+#define MAC_ID_EN                                      BIT(7)
+
+#define WLOCK_ALL                                      BIT(0)
+#define WLOCK_00                                       BIT(1)
+#define WLOCK_04                                       BIT(2)
+#define WLOCK_08                                       BIT(3)
+#define WLOCK_40                                       BIT(4)
+#define R_DIS_PRST_0                           BIT(5)
+#define R_DIS_PRST_1                           BIT(6)
+#define LOCK_ALL_EN                                    BIT(7)
+
+#define RF_EN                                          BIT(0)
+#define RF_RSTB                                                BIT(1)
+#define RF_SDMRSTB                                     BIT(2)
+
+#define LDA15_EN                                       BIT(0)
+#define LDA15_STBY                                     BIT(1)
+#define LDA15_OBUF                                     BIT(2)
+#define LDA15_REG_VOS                          BIT(3)
+#define _LDA15_VOADJ(x)                                (((x) & 0x7) << 4)
+
+#define LDV12_EN                                       BIT(0)
+#define LDV12_SDBY                                     BIT(1)
+#define LPLDO_HSM                                      BIT(2)
+#define LPLDO_LSM_DIS                          BIT(3)
+#define _LDV12_VADJ(x)                         (((x) & 0xF) << 4)
+
+#define XTAL_EN                                                BIT(0)
+#define XTAL_BSEL                                      BIT(1)
+#define _XTAL_BOSC(x)                          (((x) & 0x3) << 2)
+#define _XTAL_CADJ(x)                          (((x) & 0xF) << 4)
+#define XTAL_GATE_USB                          BIT(8)
+#define _XTAL_USB_DRV(x)                       (((x) & 0x3) << 9)
+#define XTAL_GATE_AFE                          BIT(11)
+#define _XTAL_AFE_DRV(x)                       (((x) & 0x3) << 12)
+#define XTAL_RF_GATE                           BIT(14)
+#define _XTAL_RF_DRV(x)                                (((x) & 0x3) << 15)
+#define XTAL_GATE_DIG                          BIT(17)
+#define _XTAL_DIG_DRV(x)                       (((x) & 0x3) << 18)
+#define XTAL_BT_GATE                           BIT(20)
+#define _XTAL_BT_DRV(x)                                (((x) & 0x3) << 21)
+#define _XTAL_GPIO(x)                          (((x) & 0x7) << 23)
+
+#define CKDLY_AFE                                      BIT(26)
+#define CKDLY_USB                                      BIT(27)
+#define CKDLY_DIG                                      BIT(28)
+#define CKDLY_BT                                       BIT(29)
+
+#define APLL_EN                                                BIT(0)
+#define APLL_320_EN                                    BIT(1)
+#define APLL_FREF_SEL                          BIT(2)
+#define APLL_EDGE_SEL                          BIT(3)
+#define APLL_WDOGB                                     BIT(4)
+#define APLL_LPFEN                                     BIT(5)
+
+#define APLL_REF_CLK_13MHZ                     0x1
+#define APLL_REF_CLK_19_2MHZ           0x2
+#define APLL_REF_CLK_20MHZ                     0x3
+#define APLL_REF_CLK_25MHZ                     0x4
+#define APLL_REF_CLK_26MHZ                     0x5
+#define APLL_REF_CLK_38_4MHZ           0x6
+#define APLL_REF_CLK_40MHZ                     0x7
+
+#define APLL_320EN                                     BIT(14)
+#define APLL_80EN                                      BIT(15)
+#define APLL_1MEN                                      BIT(24)
+
+#define ALD_EN                                         BIT(18)
+#define EF_PD                                          BIT(19)
+#define EF_FLAG                                                BIT(31)
+
+#define EF_TRPT                                                BIT(7)
+#define LDOE25_EN                                      BIT(31)
+
+#define RSM_EN                                         BIT(0)
+#define Timer_EN                                       BIT(4)
+
+#define TRSW0EN                                                BIT(2)
+#define TRSW1EN                                                BIT(3)
+#define EROM_EN                                                BIT(4)
+#define EnBT                                           BIT(5)
+#define EnUart                                         BIT(8)
+#define Uart_910                                       BIT(9)
+#define EnPMAC                                         BIT(10)
+#define SIC_SWRST                                      BIT(11)
+#define EnSIC                                          BIT(12)
+#define SIC_23                                         BIT(13)
+#define EnHDP                                          BIT(14)
+#define SIC_LBK                                                BIT(15)
+
+#define LED0PL                                                 BIT(4)
+#define LED1PL                                                 BIT(12)
+#define LED0DIS                                                BIT(7)
+
+#define MCUFWDL_EN                                     BIT(0)
+#define MCUFWDL_RDY                                    BIT(1)
+#define FWDL_CHKSUM_RPT                                BIT(2)
+#define MACINI_RDY                                     BIT(3)
+#define BBINI_RDY                                      BIT(4)
+#define RFINI_RDY                                      BIT(5)
+#define WINTINI_RDY                                    BIT(6)
+#define CPRST                                          BIT(23)
+
+#define XCLK_VLD                                       BIT(0)
+#define ACLK_VLD                                       BIT(1)
+#define UCLK_VLD                                       BIT(2)
+#define PCLK_VLD                                       BIT(3)
+#define PCIRSTB                                                BIT(4)
+#define V15_VLD                                                BIT(5)
+#define TRP_B15V_EN                                    BIT(7)
+#define SIC_IDLE                                       BIT(8)
+#define BD_MAC2                                                BIT(9)
+#define BD_MAC1                                                BIT(10)
+#define IC_MACPHY_MODE                         BIT(11)
+#define VENDOR_ID                                      BIT(19)
+#define PAD_HWPD_IDN                           BIT(22)
+#define TRP_VAUX_EN                                    BIT(23)
+#define TRP_BT_EN                                      BIT(24)
+#define BD_PKG_SEL                                     BIT(25)
+#define BD_HCI_SEL                                     BIT(26)
+#define TYPE_ID                                                BIT(27)
+
+#define CHIP_VER_RTL_MASK                      0xF000
+#define CHIP_VER_RTL_SHIFT                     12
+
+#define REG_LBMODE                                     (REG_CR + 3)
+
+#define HCI_TXDMA_EN                           BIT(0)
+#define HCI_RXDMA_EN                           BIT(1)
+#define TXDMA_EN                                       BIT(2)
+#define RXDMA_EN                                       BIT(3)
+#define PROTOCOL_EN                                    BIT(4)
+#define SCHEDULE_EN                                    BIT(5)
+#define MACTXEN                                                BIT(6)
+#define MACRXEN                                                BIT(7)
+#define ENSWBCN                                                BIT(8)
+#define ENSEC                                          BIT(9)
+
+#define _NETTYPE(x)                                    (((x) & 0x3) << 16)
+#define MASK_NETTYPE                           0x30000
+#define NT_NO_LINK                                     0x0
+#define NT_LINK_AD_HOC                         0x1
+#define NT_LINK_AP                                     0x2
+#define NT_AS_AP                                       0x3
+
+#define _LBMODE(x)                                     (((x) & 0xF) << 24)
+#define MASK_LBMODE                                    0xF000000
+#define LOOPBACK_NORMAL                                0x0
+#define LOOPBACK_IMMEDIATELY           0xB
+#define LOOPBACK_MAC_DELAY                     0x3
+#define LOOPBACK_PHY                           0x1
+#define LOOPBACK_DMA                           0x7
+
+#define GET_RX_PAGE_SIZE(value)                ((value) & 0xF)
+#define GET_TX_PAGE_SIZE(value)                (((value) & 0xF0) >> 4)
+#define _PSRX_MASK                                     0xF
+#define _PSTX_MASK                                     0xF0
+#define _PSRX(x)                                       (x)
+#define _PSTX(x)                                       ((x) << 4)
+
+#define PBP_64                                         0x0
+#define PBP_128                                                0x1
+#define PBP_256                                                0x2
+#define PBP_512                                                0x3
+#define PBP_1024                                       0x4
+
+#define RXDMA_ARBBW_EN                         BIT(0)
+#define RXSHFT_EN                                      BIT(1)
+#define RXDMA_AGG_EN                           BIT(2)
+#define QS_VO_QUEUE                                    BIT(8)
+#define QS_VI_QUEUE                                    BIT(9)
+#define QS_BE_QUEUE                                    BIT(10)
+#define QS_BK_QUEUE                                    BIT(11)
+#define QS_MANAGER_QUEUE                       BIT(12)
+#define QS_HIGH_QUEUE                          BIT(13)
+
+#define HQSEL_VOQ                                      BIT(0)
+#define HQSEL_VIQ                                      BIT(1)
+#define HQSEL_BEQ                                      BIT(2)
+#define HQSEL_BKQ                                      BIT(3)
+#define HQSEL_MGTQ                                     BIT(4)
+#define HQSEL_HIQ                                      BIT(5)
+
+#define _TXDMA_HIQ_MAP(x)                      (((x)&0x3) << 14)
+#define _TXDMA_MGQ_MAP(x)                      (((x)&0x3) << 12)
+#define _TXDMA_BKQ_MAP(x)                      (((x)&0x3) << 10)
+#define _TXDMA_BEQ_MAP(x)                      (((x)&0x3) << 8 )
+#define _TXDMA_VIQ_MAP(x)                      (((x)&0x3) << 6 )
+#define _TXDMA_VOQ_MAP(x)                      (((x)&0x3) << 4 )
+
+#define QUEUE_LOW                                      1
+#define QUEUE_NORMAL                           2
+#define QUEUE_HIGH                                     3
+
+#define _LLT_NO_ACTIVE                         0x0
+#define _LLT_WRITE_ACCESS                      0x1
+#define _LLT_READ_ACCESS                       0x2
+
+#define _LLT_INIT_DATA(x)                      ((x) & 0xFF)
+#define _LLT_INIT_ADDR(x)                      (((x) & 0xFF) << 8)
+#define _LLT_OP(x)                                     (((x) & 0x3) << 30)
+#define _LLT_OP_VALUE(x)                       (((x) >> 30) & 0x3)
+
+#define BB_WRITE_READ_MASK                     (BIT(31) | BIT(30))
+#define BB_WRITE_EN                                    BIT(30)
+#define BB_READ_EN                                     BIT(31)
+
+#define _HPQ(x)                        ((x) & 0xFF)
+#define _LPQ(x)                        (((x) & 0xFF) << 8)
+#define _PUBQ(x)               (((x) & 0xFF) << 16)
+#define _NPQ(x)                        ((x) & 0xFF)
+
+#define HPQ_PUBLIC_DIS         BIT(24)
+#define LPQ_PUBLIC_DIS         BIT(25)
+#define LD_RQPN                        BIT(31)
+
+#define BCN_VALID              BIT(16)
+#define BCN_HEAD(x)            (((x) & 0xFF) << 8)
+#define        BCN_HEAD_MASK           0xFF00
+
+#define BLK_DESC_NUM_SHIFT                     4
+#define BLK_DESC_NUM_MASK                      0xF
+
+#define DROP_DATA_EN                           BIT(9)
+
+#define EN_AMPDU_RTY_NEW                       BIT(7)
+
+#define _INIRTSMCS_SEL(x)                      ((x) & 0x3F)
+
+#define _SPEC_SIFS_CCK(x)                      ((x) & 0xFF)
+#define _SPEC_SIFS_OFDM(x)                     (((x) & 0xFF) << 8)
+
+#define RATE_REG_BITMAP_ALL                    0xFFFFF
+
+#define _RRSC_BITMAP(x)                                ((x) & 0xFFFFF)
+
+#define _RRSR_RSC(x)                           (((x) & 0x3) << 21)
+#define RRSR_RSC_RESERVED                      0x0
+#define RRSR_RSC_UPPER_SUBCHANNEL      0x1
+#define RRSR_RSC_LOWER_SUBCHANNEL      0x2
+#define RRSR_RSC_DUPLICATE_MODE                0x3
+
+#define USE_SHORT_G1                           BIT(20)
+
+#define _AGGLMT_MCS0(x)                                ((x) & 0xF)
+#define _AGGLMT_MCS1(x)                                (((x) & 0xF) << 4)
+#define _AGGLMT_MCS2(x)                                (((x) & 0xF) << 8)
+#define _AGGLMT_MCS3(x)                                (((x) & 0xF) << 12)
+#define _AGGLMT_MCS4(x)                                (((x) & 0xF) << 16)
+#define _AGGLMT_MCS5(x)                                (((x) & 0xF) << 20)
+#define _AGGLMT_MCS6(x)                                (((x) & 0xF) << 24)
+#define _AGGLMT_MCS7(x)                                (((x) & 0xF) << 28)
+
+#define        RETRY_LIMIT_SHORT_SHIFT         8
+#define        RETRY_LIMIT_LONG_SHIFT          0
+
+#define _DARF_RC1(x)                           ((x) & 0x1F)
+#define _DARF_RC2(x)                           (((x) & 0x1F) << 8)
+#define _DARF_RC3(x)                           (((x) & 0x1F) << 16)
+#define _DARF_RC4(x)                           (((x) & 0x1F) << 24)
+#define _DARF_RC5(x)                           ((x) & 0x1F)
+#define _DARF_RC6(x)                           (((x) & 0x1F) << 8)
+#define _DARF_RC7(x)                           (((x) & 0x1F) << 16)
+#define _DARF_RC8(x)                           (((x) & 0x1F) << 24)
+
+#define _RARF_RC1(x)                           ((x) & 0x1F)
+#define _RARF_RC2(x)                           (((x) & 0x1F) << 8)
+#define _RARF_RC3(x)                           (((x) & 0x1F) << 16)
+#define _RARF_RC4(x)                           (((x) & 0x1F) << 24)
+#define _RARF_RC5(x)                           ((x) & 0x1F)
+#define _RARF_RC6(x)                           (((x) & 0x1F) << 8)
+#define _RARF_RC7(x)                           (((x) & 0x1F) << 16)
+#define _RARF_RC8(x)                           (((x) & 0x1F) << 24)
+
+#define AC_PARAM_TXOP_LIMIT_OFFSET     16
+#define AC_PARAM_ECW_MAX_OFFSET                12
+#define AC_PARAM_ECW_MIN_OFFSET                8
+#define AC_PARAM_AIFS_OFFSET           0
+
+#define _AIFS(x)                                       (x)
+#define _ECW_MAX_MIN(x)                                ((x) << 8)
+#define _TXOP_LIMIT(x)                         ((x) << 16)
+
+#define _BCNIFS(x)                                     ((x) & 0xFF)
+#define _BCNECW(x)                                     ((((x) & 0xF))<< 8)
+
+#define _LRL(x)                                                ((x) & 0x3F)
+#define _SRL(x)                                                (((x) & 0x3F) << 8)
+
+#define _SIFS_CCK_CTX(x)                       ((x) & 0xFF)
+#define _SIFS_CCK_TRX(x)                       (((x) & 0xFF) << 8);
+
+#define _SIFS_OFDM_CTX(x)                      ((x) & 0xFF)
+#define _SIFS_OFDM_TRX(x)                      (((x) & 0xFF) << 8);
+
+#define _TBTT_PROHIBIT_HOLD(x)         (((x) & 0xFF) << 8)
+
+#define DIS_EDCA_CNT_DWN                       BIT(11)
+
+#define EN_MBSSID                                      BIT(1)
+#define EN_TXBCN_RPT                           BIT(2)
+#define        EN_BCN_FUNCTION                         BIT(3)
+
+#define TSFTR_RST                                      BIT(0)
+#define TSFTR1_RST                                     BIT(1)
+
+#define STOP_BCNQ                                      BIT(6)
+
+#define        DIS_TSF_UDT0_NORMAL_CHIP        BIT(4)
+#define        DIS_TSF_UDT0_TEST_CHIP          BIT(5)
+
+#define        AcmHw_HwEn                                      BIT(0)
+#define        AcmHw_BeqEn                                     BIT(1)
+#define        AcmHw_ViqEn                                     BIT(2)
+#define        AcmHw_VoqEn                                     BIT(3)
+#define        AcmHw_BeqStatus                         BIT(4)
+#define        AcmHw_ViqStatus                         BIT(5)
+#define        AcmHw_VoqStatus                         BIT(6)
+
+#define APSDOFF                                                BIT(6)
+#define APSDOFF_STATUS                         BIT(7)
+
+#define BW_20MHZ                                       BIT(2)
+
+#define RATE_BITMAP_ALL                                0xFFFFF
+
+#define RATE_RRSR_CCK_ONLY_1M          0xFFFF1
+
+#define TSFRST                                         BIT(0)
+#define DIS_GCLK                                       BIT(1)
+#define PAD_SEL                                                BIT(2)
+#define PWR_ST                                         BIT(6)
+#define PWRBIT_OW_EN                           BIT(7)
+#define ACRC                                           BIT(8)
+#define CFENDFORM                                      BIT(9)
+#define ICV                                                    BIT(10)
+
+#define AAP                                                    BIT(0)
+#define APM                                                    BIT(1)
+#define AM                                                     BIT(2)
+#define AB                                                     BIT(3)
+#define ADD3                                           BIT(4)
+#define APWRMGT                                                BIT(5)
+#define CBSSID                                         BIT(6)
+#define CBSSID_DATA                                    BIT(6)
+#define CBSSID_BCN                                     BIT(7)
+#define ACRC32                                         BIT(8)
+#define AICV                                           BIT(9)
+#define ADF                                                    BIT(11)
+#define ACF                                                    BIT(12)
+#define AMF                                                    BIT(13)
+#define HTC_LOC_CTRL                           BIT(14)
+#define UC_DATA_EN                                     BIT(16)
+#define BM_DATA_EN                                     BIT(17)
+#define MFBEN                                          BIT(22)
+#define LSIGEN                                         BIT(23)
+#define EnMBID                                         BIT(24)
+#define APP_BASSN                                      BIT(27)
+#define APP_PHYSTS                                     BIT(28)
+#define APP_ICV                                                BIT(29)
+#define APP_MIC                                                BIT(30)
+#define APP_FCS                                                BIT(31)
+
+#define _MIN_SPACE(x)                          ((x) & 0x7)
+#define _SHORT_GI_PADDING(x)           (((x) & 0x1F) << 3)
+
+#define RXERR_TYPE_OFDM_PPDU           0
+#define RXERR_TYPE_OFDM_FALSE_ALARM    1
+#define        RXERR_TYPE_OFDM_MPDU_OK         2
+#define RXERR_TYPE_OFDM_MPDU_FAIL      3
+#define RXERR_TYPE_CCK_PPDU                    4
+#define RXERR_TYPE_CCK_FALSE_ALARM     5
+#define RXERR_TYPE_CCK_MPDU_OK         6
+#define RXERR_TYPE_CCK_MPDU_FAIL       7
+#define RXERR_TYPE_HT_PPDU                     8
+#define RXERR_TYPE_HT_FALSE_ALARM      9
+#define RXERR_TYPE_HT_MPDU_TOTAL       10
+#define RXERR_TYPE_HT_MPDU_OK          11
+#define RXERR_TYPE_HT_MPDU_FAIL                12
+#define RXERR_TYPE_RX_FULL_DROP                15
+
+#define RXERR_COUNTER_MASK                     0xFFFFF
+#define RXERR_RPT_RST                          BIT(27)
+#define _RXERR_RPT_SEL(type)           ((type) << 28)
+
+#define        SCR_TxUseDK                                     BIT(0)
+#define        SCR_RxUseDK                                     BIT(1)
+#define        SCR_TxEncEnable                         BIT(2)
+#define        SCR_RxDecEnable                         BIT(3)
+#define        SCR_SKByA2                                      BIT(4)
+#define        SCR_NoSKMC                                      BIT(5)
+#define SCR_TXBCUSEDK                          BIT(6)
+#define SCR_RXBCUSEDK                          BIT(7)
+
+#define XCLK_VLD                                       BIT(0)
+#define ACLK_VLD                                       BIT(1)
+#define UCLK_VLD                                       BIT(2)
+#define PCLK_VLD                                       BIT(3)
+#define PCIRSTB                                                BIT(4)
+#define V15_VLD                                                BIT(5)
+#define TRP_B15V_EN                                    BIT(7)
+#define SIC_IDLE                                       BIT(8)
+#define BD_MAC2                                                BIT(9)
+#define BD_MAC1                                                BIT(10)
+#define IC_MACPHY_MODE                         BIT(11)
+#define BT_FUNC                                                BIT(16)
+#define VENDOR_ID                                      BIT(19)
+#define PAD_HWPD_IDN                           BIT(22)
+#define TRP_VAUX_EN                                    BIT(23)
+#define TRP_BT_EN                                      BIT(24)
+#define BD_PKG_SEL                                     BIT(25)
+#define BD_HCI_SEL                                     BIT(26)
+#define TYPE_ID                                                BIT(27)
+
+#define USB_IS_HIGH_SPEED                      0
+#define USB_IS_FULL_SPEED                      1
+#define USB_SPEED_MASK                         BIT(5)
+
+#define USB_NORMAL_SIE_EP_MASK         0xF
+#define USB_NORMAL_SIE_EP_SHIFT                4
+
+#define USB_TEST_EP_MASK                       0x30
+#define USB_TEST_EP_SHIFT                      4
+
+#define USB_AGG_EN                                     BIT(3)
+
+#define MAC_ADDR_LEN                           6
+#define LAST_ENTRY_OF_TX_PKT_BUFFER    175/*255    88e*/
+
+#define POLLING_LLT_THRESHOLD          20
+#define POLLING_READY_TIMEOUT_COUNT            3000
+
+#define        MAX_MSS_DENSITY_2T                      0x13
+#define        MAX_MSS_DENSITY_1T                      0x0A
+
+#define EPROM_CMD_OPERATING_MODE_MASK  ((1<<7)|(1<<6))
+#define EPROM_CMD_CONFIG                       0x3
+#define EPROM_CMD_LOAD                                 1
+
+#define        HWSET_MAX_SIZE_92S                      HWSET_MAX_SIZE
+
+#define        HAL_8192C_HW_GPIO_WPS_BIT       BIT(2)
+
+#define RA_LSSIWRITE_8821A                     0xc90
+#define RB_LSSIWRITE_8821A                     0xe90
+
+#define        RA_PIREAD_8821A         0xd04
+#define        RB_PIREAD_8821A         0xd44
+#define        RA_SIREAD_8821A         0xd08
+#define        RB_SIREAD_8821A         0xd48
+
+#define        RPMAC_RESET                                     0x100
+#define        RPMAC_TXSTART                           0x104
+#define        RPMAC_TXLEGACYSIG                       0x108
+#define        RPMAC_TXHTSIG1                          0x10c
+#define        RPMAC_TXHTSIG2                          0x110
+#define        RPMAC_PHYDEBUG                          0x114
+#define        RPMAC_TXPACKETNUM                       0x118
+#define        RPMAC_TXIDLE                            0x11c
+#define        RPMAC_TXMACHEADER0                      0x120
+#define        RPMAC_TXMACHEADER1                      0x124
+#define        RPMAC_TXMACHEADER2                      0x128
+#define        RPMAC_TXMACHEADER3                      0x12c
+#define        RPMAC_TXMACHEADER4                      0x130
+#define        RPMAC_TXMACHEADER5                      0x134
+#define        RPMAC_TXDADATYPE                        0x138
+#define        RPMAC_TXRANDOMSEED                      0x13c
+#define        RPMAC_CCKPLCPPREAMBLE           0x140
+#define        RPMAC_CCKPLCPHEADER                     0x144
+#define        RPMAC_CCKCRC16                          0x148
+#define        RPMAC_OFDMRXCRC32OK                     0x170
+#define        RPMAC_OFDMRXCRC32Er                     0x174
+#define        RPMAC_OFDMRXPARITYER            0x178
+#define        RPMAC_OFDMRXCRC8ER                      0x17c
+#define        RPMAC_CCKCRXRC16ER                      0x180
+#define        RPMAC_CCKCRXRC32ER                      0x184
+#define        RPMAC_CCKCRXRC32OK                      0x188
+#define        RPMAC_TXSTATUS                          0x18c
+
+#define        RFPGA0_RFMOD                            0x800
+
+#define        RFPGA0_TXINFO                           0x804
+#define        RFPGA0_PSDFUNCTION                      0x808
+
+#define        RFPGA0_TXGAINSTAGE                      0x80c
+
+#define        RFPGA0_RFTIMING1                        0x810
+#define        RFPGA0_RFTIMING2                        0x814
+
+#define        RFPGA0_XA_HSSIPARAMETER1        0x820
+#define        RFPGA0_XA_HSSIPARAMETER2        0x824
+#define        RFPGA0_XB_HSSIPARAMETER1        0x828
+#define        RFPGA0_XB_HSSIPARAMETER2        0x82c
+#define        RCCAONSEC                                       0x838
+
+#define        RFPGA0_XA_LSSIPARAMETER         0x840
+#define        RFPGA0_XB_LSSIPARAMETER         0x844
+#define        RL1PEAKTH                                       0x848
+
+#define        RFPGA0_RFWAKEUPPARAMETER        0x850
+#define        RFPGA0_RFSLEEPUPPARAMETER       0x854
+
+#define        RFPGA0_XAB_SWITCHCONTROL        0x858
+#define        RFPGA0_XCD_SWITCHCONTROL        0x85c
+
+#define        RFPGA0_XA_RFINTERFACEOE         0x860
+#define RFC_AREA                                       0x860
+#define        RFPGA0_XB_RFINTERFACEOE         0x864
+
+#define        RFPGA0_XAB_RFINTERFACESW        0x870
+#define        RFPGA0_XCD_RFINTERFACESW        0x874
+
+#define        rFPGA0_XAB_RFPARAMETER          0x878
+#define        rFPGA0_XCD_RFPARAMETER          0x87c
+
+#define        RFPGA0_ANALOGPARAMETER1         0x880
+#define        RFPGA0_ANALOGPARAMETER2         0x884
+#define        RFPGA0_ANALOGPARAMETER3         0x888
+#define        RFPGA0_ANALOGPARAMETER4         0x88c
+
+#define        RFPGA0_XA_LSSIREADBACK          0x8a0
+#define        RFPGA0_XB_LSSIREADBACK          0x8a4
+#define        RFPGA0_XC_LSSIREADBACK          0x8a8
+//#define      RFPGA0_XD_LSSIREADBACK          0x8ac
+#define RRFMOD                                         0x8ac
+#define        RHSSIREAD_8821AE                        0x8b0
+
+#define        RFPGA0_PSDREPORT                        0x8b4
+#define        TRANSCEIVEA_HSPI_READBACK       0x8b8
+#define        TRANSCEIVEB_HSPI_READBACK       0x8bc
+//#define      REG_SC_CNT                                      0x8c4
+#define RADC_BUF_CLK                           0x8c4
+#define        RFPGA0_XAB_RFINTERFACERB        0x8e0
+#define        RFPGA0_XCD_RFINTERFACERB        0x8e4
+
+#define        RFPGA1_RFMOD                            0x900
+
+#define        RFPGA1_TXBLOCK                          0x904
+#define        RFPGA1_DEBUGSELECT                      0x908
+#define        RFPGA1_TXINFO                           0x90c
+
+#define        RCCK_SYSTEM                                     0xa00
+#define        BCCK_SYSTEM                                     0x10
+
+
+#define        RCCK0_AFESETTING                        0xa04
+#define        RCCK0_CCA                                       0xa08
+
+#define        RCCK0_RXAGC1                            0xa0c
+#define        RCCK0_RXAGC2                            0xa10
+
+#define        RCCK0_RXHP                                      0xa14
+
+#define        RCCK0_DSPPARAMETER1                     0xa18
+#define        RCCK0_DSPPARAMETER2                     0xa1c
+
+#define        RCCK0_TXFILTER1                         0xa20
+#define        RCCK0_TXFILTER2                         0xa24
+#define        RCCK0_DEBUGPORT                         0xa28
+#define        RCCK0_FALSEALARMREPORT          0xa2c
+#define        RCCK0_TRSSIREPORT               0xa50
+#define        RCCK0_RXREPORT                  0xa54
+#define        RCCK0_FACOUNTERLOWER            0xa5c
+#define        RCCK0_FACOUNTERUPPER            0xa58
+#define        RCCK0_CCA_CNT                   0xa60
+
+
+/* PageB(0xB00) */
+#define        rPdp_AntA                                       0xb00
+#define        rPdp_AntA_4                             0xb04
+#define        rPdp_AntA_8                             0xb08
+#define        rPdp_AntA_C                             0xb0c
+#define        rPdp_AntA_10                                    0xb10
+#define        rPdp_AntA_14                                    0xb14
+#define        rPdp_AntA_18                                    0xb18
+#define        rPdp_AntA_1C                                    0xb1c
+#define        rPdp_AntA_20                                    0xb20
+#define        rPdp_AntA_24                                    0xb24
+
+#define        rConfig_Pmpd_AntA                       0xb28
+#define        rConfig_ram64x16                                0xb2c
+
+#define        rBndA                                           0xb30
+#define        rHssiPar                                                0xb34
+
+#define        rConfig_AntA                                    0xb68
+#define        rConfig_AntB                                    0xb6c
+
+#define        rPdp_AntB                                       0xb70
+#define        rPdp_AntB_4                                     0xb74
+#define        rPdp_AntB_8                                     0xb78
+#define        rPdp_AntB_C                                     0xb7c
+#define        rPdp_AntB_10                                    0xb80
+#define        rPdp_AntB_14                                    0xb84
+#define        rPdp_AntB_18                                    0xb88
+#define        rPdp_AntB_1C                                    0xb8c
+#define        rPdp_AntB_20                                    0xb90
+#define        rPdp_AntB_24                                    0xb94
+
+#define        rConfig_Pmpd_AntB                       0xb98
+
+#define        rBndB                                           0xba0
+
+#define        rAPK                                                    0xbd8
+#define        rPm_Rx0_AntA                            0xbdc
+#define        rPm_Rx1_AntA                            0xbe0
+#define        rPm_Rx2_AntA                            0xbe4
+#define        rPm_Rx3_AntA                            0xbe8
+#define        rPm_Rx0_AntB                            0xbec
+#define        rPm_Rx1_AntB                            0xbf0
+#define        rPm_Rx2_AntB                            0xbf4
+#define        rPm_Rx3_AntB                            0xbf8
+
+/*RSSI Dump*/
+#define                RA_RSSI_DUMP            0xBF0
+#define                RB_RSSI_DUMP            0xBF1
+#define                RS1_RX_EVM_DUMP 0xBF4
+#define                RS2_RX_EVM_DUMP 0xBF5
+#define                RA_RX_SNR_DUMP          0xBF6
+#define                RB_RX_SNR_DUMP          0xBF7
+#define                RA_CFO_SHORT_DUMP       0xBF8
+#define                RB_CFO_SHORT_DUMP       0xBFA
+#define                RA_CFO_LONG_DUMP        0xBEC
+#define                RB_CFO_LONG_DUMP        0xBEE
+
+/*Page C*/
+#define        ROFDM0_LSTF                                     0xc00
+
+#define        ROFDM0_TRXPATHENABLE            0xc04
+#define        ROFDM0_TRMUXPAR                         0xc08
+#define        ROFDM0_TRSWISOLATION            0xc0c
+
+#define        ROFDM0_XARXAFE                          0xc10
+#define        ROFDM0_XARXIQIMBALANCE          0xc14
+#define        ROFDM0_XBRXAFE                  0xc18
+#define        ROFDM0_XBRXIQIMBALANCE          0xc1c
+#define        ROFDM0_XCRXAFE                  0xc20
+#define        ROFDM0_XCRXIQIMBANLANCE         0xc24
+#define        ROFDM0_XDRXAFE                  0xc28
+#define        ROFDM0_XDRXIQIMBALANCE          0xc2c
+
+#define        ROFDM0_RXDETECTOR1                      0xc30
+#define        ROFDM0_RXDETECTOR2                      0xc34
+#define        ROFDM0_RXDETECTOR3                      0xc38
+#define        ROFDM0_RXDETECTOR4                      0xc3c
+
+#define        ROFDM0_RXDSP                            0xc40
+#define        ROFDM0_CFOANDDAGC                       0xc44
+#define        ROFDM0_CCADROPTHRESHOLD         0xc48
+#define        ROFDM0_ECCATHRESHOLD            0xc4c
+
+#define        ROFDM0_XAAGCCORE1                       0xc50
+#define        ROFDM0_XAAGCCORE2                       0xc54
+#define        ROFDM0_XBAGCCORE1                       0xc58
+#define        ROFDM0_XBAGCCORE2                       0xc5c
+#define        ROFDM0_XCAGCCORE1                       0xc60
+#define        ROFDM0_XCAGCCORE2                       0xc64
+#define        ROFDM0_XDAGCCORE1                       0xc68
+#define        ROFDM0_XDAGCCORE2                       0xc6c
+
+#define        ROFDM0_AGCPARAMETER1            0xc70
+#define        ROFDM0_AGCPARAMETER2            0xc74
+#define        ROFDM0_AGCRSSITABLE                     0xc78
+#define        ROFDM0_HTSTFAGC                         0xc7c
+
+#define        ROFDM0_XATXIQIMBALANCE          0xc80
+#define        ROFDM0_XATXAFE                          0xc84
+#define        ROFDM0_XBTXIQIMBALANCE          0xc88
+#define        ROFDM0_XBTXAFE                          0xc8c
+#define        ROFDM0_XCTXIQIMBALANCE          0xc90
+#define        ROFDM0_XCTXAFE                  0xc94
+#define        ROFDM0_XDTXIQIMBALANCE          0xc98
+#define        ROFDM0_XDTXAFE                          0xc9c
+
+#define ROFDM0_RXIQEXTANTA                     0xca0
+#define        ROFDM0_TXCOEFF1                         0xca4
+#define        ROFDM0_TXCOEFF2                         0xca8
+#define        ROFDM0_TXCOEFF3                         0xcac
+#define        ROFDM0_TXCOEFF4                         0xcb0
+#define        ROFDM0_TXCOEFF5                         0xcb4
+#define        ROFDM0_TXCOEFF6                         0xcb8
+
+/*Path_A RFE cotrol */
+#define        RA_RFE_CTRL_8812                                0xcb8
+/*Path_B RFE control*/
+#define        RB_RFE_CTRL_8812                                0xeb8
+
+#define        ROFDM0_RXHPPARAMETER            0xce0
+#define        ROFDM0_TXPSEUDONOISEWGT         0xce4
+#define        ROFDM0_FRAMESYNC                        0xcf0
+#define        ROFDM0_DFSREPORT                        0xcf4
+
+
+#define        ROFDM1_LSTF                                     0xd00
+#define        ROFDM1_TRXPATHENABLE            0xd04
+
+#define        ROFDM1_CF0                                      0xd08
+#define        ROFDM1_CSI1                                     0xd10
+#define        ROFDM1_SBD                                      0xd14
+#define        ROFDM1_CSI2                                     0xd18
+#define        ROFDM1_CFOTRACKING                      0xd2c
+#define        ROFDM1_TRXMESAURE1                      0xd34
+#define        ROFDM1_INTFDET                          0xd3c
+#define        ROFDM1_PSEUDONOISESTATEAB       0xd50
+#define        ROFDM1_PSEUDONOISESTATECD       0xd54
+#define        ROFDM1_RXPSEUDONOISEWGT         0xd58
+
+#define        ROFDM_PHYCOUNTER1                       0xda0
+#define        ROFDM_PHYCOUNTER2                       0xda4
+#define        ROFDM_PHYCOUNTER3                       0xda8
+
+#define        ROFDM_SHORTCFOAB                        0xdac
+#define        ROFDM_SHORTCFOCD                        0xdb0
+#define        ROFDM_LONGCFOAB                         0xdb4
+#define        ROFDM_LONGCFOCD                         0xdb8
+#define        ROFDM_TAILCF0AB                         0xdbc
+#define        ROFDM_TAILCF0CD                         0xdc0
+#define        ROFDM_PWMEASURE1                0xdc4
+#define        ROFDM_PWMEASURE2                0xdc8
+#define        ROFDM_BWREPORT                          0xdcc
+#define        ROFDM_AGCREPORT                         0xdd0
+#define        ROFDM_RXSNR                                     0xdd4
+#define        ROFDM_RXEVMCSI                          0xdd8
+#define        ROFDM_SIGREPORT                         0xddc
+
+#define RTXAGC_A_CCK11_CCK1                    0xc20
+#define RTXAGC_A_OFDM18_OFDM6          0xc24
+#define RTXAGC_A_OFDM54_OFDM24         0xc28
+#define RTXAGC_A_MCS03_MCS00                   0xc2c
+#define RTXAGC_A_MCS07_MCS04                   0xc30
+#define RTXAGC_A_MCS11_MCS08                   0xc34
+#define RTXAGC_A_MCS15_MCS12           0xc38
+#define RTXAGC_A_NSS1INDEX3_NSS1INDEX0 0xc3c
+#define        RTXAGC_A_NSS1INDEX7_NSS1INDEX4  0xc40
+#define        RTXAGC_A_NSS2INDEX1_NSS1INDEX8  0xc44
+#define        RTXAGC_A_NSS2INDEX5_NSS2INDEX2  0xc48
+#define        RTXAGC_A_NSS2INDEX9_NSS2INDEX6  0xc4c
+#define        RTXAGC_B_CCK11_CCK1                     0xe20
+#define        RTXAGC_B_OFDM18_OFDM6           0xe24
+#define        RTXAGC_B_OFDM54_OFDM24          0xe28
+#define        RTXAGC_B_MCS03_MCS00                    0xe2c
+#define        RTXAGC_B_MCS07_MCS04                    0xe30
+#define        RTXAGC_B_MCS11_MCS08                    0xe34
+#define        RTXAGC_B_MCS15_MCS12            0xe38
+#define        RTXAGC_B_NSS1INDEX3_NSS1INDEX0  0xe3c
+#define        RTXAGC_B_NSS1INDEX7_NSS1INDEX4  0xe40
+#define        RTXAGC_B_NSS2INDEX1_NSS1INDEX8  0xe44
+#define        RTXAGC_B_NSS2INDEX5_NSS2INDEX2  0xe48
+#define        RTXAGC_B_NSS2INDEX9_NSS2INDEX6  0xe4c
+
+#define        RA_TXPWRTRAING          0xc54
+#define        RB_TXPWRTRAING          0xe54
+
+
+#define        RFPGA0_IQK                                      0xe28
+#define        RTx_IQK_Tone_A                          0xe30
+#define        RRx_IQK_Tone_A                          0xe34
+#define        RTx_IQK_PI_A                                    0xe38
+#define        RRx_IQK_PI_A                                    0xe3c
+
+#define        RTx_IQK                                                 0xe40
+#define        RRx_IQK                                         0xe44
+#define        RIQK_AGC_Pts                                    0xe48
+#define        RIQK_AGC_Rsp                                    0xe4c
+#define        RTx_IQK_Tone_B                          0xe50
+#define        RRx_IQK_Tone_B                          0xe54
+#define        RTx_IQK_PI_B                                    0xe58
+#define        RRx_IQK_PI_B                                    0xe5c
+#define        RIQK_AGC_Cont                           0xe60
+
+#define        RBlue_Tooth                                     0xe6c
+#define        RRx_Wait_CCA                                    0xe70
+#define        RTx_CCK_RFON                                    0xe74
+#define        RTx_CCK_BBON                            0xe78
+#define        RTx_OFDM_RFON                           0xe7c
+#define        RTx_OFDM_BBON                           0xe80
+#define        RTx_To_Rx                                       0xe84
+#define        RTx_To_Tx                                       0xe88
+#define        RRx_CCK                                         0xe8c
+
+#define        RTx_Power_Before_IQK_A          0xe94
+#define        RTx_Power_After_IQK_A                   0xe9c
+
+#define        RRx_Power_Before_IQK_A          0xea0
+#define        RRx_Power_Before_IQK_A_2                0xea4
+#define        RRx_Power_After_IQK_A                   0xea8
+#define        RRx_Power_After_IQK_A_2         0xeac
+
+#define        RTx_Power_Before_IQK_B          0xeb4
+#define        RTx_Power_After_IQK_B                   0xebc
+
+#define        RRx_Power_Before_IQK_B          0xec0
+#define        RRx_Power_Before_IQK_B_2                0xec4
+#define        RRx_Power_After_IQK_B                   0xec8
+#define        RRx_Power_After_IQK_B_2         0xecc
+
+#define        RRx_OFDM                                        0xed0
+#define        RRx_Wait_RIFS                           0xed4
+#define        RRx_TO_Rx                                       0xed8
+#define        RStandby                                                0xedc
+#define        RSleep                                          0xee0
+#define        RPMPD_ANAEN                             0xeec
+
+#define        RZEBRA1_HSSIENABLE                      0x0
+#define        RZEBRA1_TRXENABLE1                      0x1
+#define        RZEBRA1_TRXENABLE2                      0x2
+#define        RZEBRA1_AGC                                     0x4
+#define        RZEBRA1_CHARGEPUMP                      0x5
+#define        RZEBRA1_CHANNEL                         0x7
+
+#define        RZEBRA1_TXGAIN                          0x8
+#define        RZEBRA1_TXLPF                           0x9
+#define        RZEBRA1_RXLPF                           0xb
+#define        RZEBRA1_RXHPFCORNER                     0xc
+
+#define        RGLOBALCTRL                                     0
+#define        RRTL8256_TXLPF                          19
+#define        RRTL8256_RXLPF                          11
+#define        RRTL8258_TXLPF                          0x11
+#define        RRTL8258_RXLPF                          0x13
+#define        RRTL8258_RSSILPF                        0xa
+
+#define        RF_AC                                           0x00
+
+#define        RF_IQADJ_G1                                     0x01
+#define        RF_IQADJ_G2                                     0x02
+#define        RF_POW_TRSW                                     0x05
+
+#define        RF_GAIN_RX                                      0x06
+#define        RF_GAIN_TX                                      0x07
+
+#define        RF_TXM_IDAC                                     0x08
+#define        RF_BS_IQGEN                                     0x0F
+
+#define        RF_MODE1                                        0x10
+#define        RF_MODE2                                        0x11
+
+#define        RF_RX_AGC_HP                            0x12
+#define        RF_TX_AGC                                       0x13
+#define        RF_BIAS                                         0x14
+#define        RF_IPA                                          0x15
+#define        RF_POW_ABILITY                          0x17
+#define        RF_MODE_AG                                      0x18
+#define        RRFCHANNEL                                      0x18
+#define        RF_CHNLBW                                       0x18
+#define        RF_TOP                                          0x19
+
+#define        RF_RX_G1                                        0x1A
+#define        RF_RX_G2                                        0x1B
+
+#define        RF_RX_BB2                                       0x1C
+#define        RF_RX_BB1                                       0x1D
+
+#define        RF_RCK1                                         0x1E
+#define        RF_RCK2                                         0x1F
+
+#define        RF_TX_G1                                        0x20
+#define        RF_TX_G2                                        0x21
+#define        RF_TX_G3                                        0x22
+
+#define        RF_TX_BB1                                       0x23
+#define        RF_T_METER                                      0x24
+#define        RF_T_METER_88E                          0x42
+#define  RF_T_METER_8812A              0x42
+
+#define        RF_SYN_G1                                       0x25
+#define        RF_SYN_G2                                       0x26
+#define        RF_SYN_G3                                       0x27
+#define        RF_SYN_G4                                       0x28
+#define        RF_SYN_G5                                       0x29
+#define        RF_SYN_G6                                       0x2A
+#define        RF_SYN_G7                                       0x2B
+#define        RF_SYN_G8                                       0x2C
+
+#define        RF_RCK_OS                                       0x30
+#define        RF_TXPA_G1                                      0x31
+#define        RF_TXPA_G2                                      0x32
+#define        RF_TXPA_G3                                      0x33
+
+#define        RF_TX_BIAS_A                                    0x35
+#define        RF_TX_BIAS_D                                    0x36
+#define        RF_LOBF_9                                       0x38
+#define        RF_RXRF_A3                                      0x3C
+#define        RF_TRSW                                         0x3F
+
+#define        RF_TXRF_A2                                      0x41
+#define        RF_TXPA_G4                                      0x46
+#define        RF_TXPA_A4                                      0x4B
+
+#define RF_APK                                         0x63
+
+#define        RF_WE_LUT                                       0xEF
+
+#define        BBBRESETB                                       0x100
+#define        BGLOBALRESETB                           0x200
+#define        BOFDMTXSTART                            0x4
+#define        BCCKTXSTART                                     0x8
+#define        BCRC32DEBUG                                     0x100
+#define        BPMACLOOPBACK                           0x10
+#define        BTXLSIG                                         0xffffff
+#define        BOFDMTXRATE                                     0xf
+#define        BOFDMTXRESERVED                         0x10
+#define        BOFDMTXLENGTH                           0x1ffe0
+#define        BOFDMTXPARITY                           0x20000
+#define        BTXHTSIG1                                       0xffffff
+#define        BTXHTMCSRATE                            0x7f
+#define        BTXHTBW                                         0x80
+#define        BTXHTLENGTH                                     0xffff00
+#define        BTXHTSIG2                                       0xffffff
+#define        BTXHTSMOOTHING                          0x1
+#define        BTXHTSOUNDING                           0x2
+#define        BTXHTRESERVED                           0x4
+#define        BTXHTAGGREATION                         0x8
+#define        BTXHTSTBC                                       0x30
+#define        BTXHTADVANCECODING                      0x40
+#define        BTXHTSHORTGI                            0x80
+#define        BTXHTNUMBERHT_LTF                       0x300
+#define        BTXHTCRC8                                       0x3fc00
+#define        BCOUNTERRESET                           0x10000
+#define        BNUMOFOFDMTX                            0xffff
+#define        BNUMOFCCKTX                                     0xffff0000
+#define        BTXIDLEINTERVAL                         0xffff
+#define        BOFDMSERVICE                            0xffff0000
+#define        BTXMACHEADER                            0xffffffff
+#define        BTXDATAINIT                                     0xff
+#define        BTXHTMODE                                       0x100
+#define        BTXDATATYPE                                     0x30000
+#define        BTXRANDOMSEED                           0xffffffff
+#define        BCCKTXPREAMBLE                          0x1
+#define        BCCKTXSFD                                       0xffff0000
+#define        BCCKTXSIG                                       0xff
+#define        BCCKTXSERVICE                           0xff00
+#define        BCCKLENGTHEXT                           0x8000
+#define        BCCKTXLENGHT                            0xffff0000
+#define        BCCKTXCRC16                                     0xffff
+#define        BCCKTXSTATUS                            0x1
+#define        BOFDMTXSTATUS                           0x2
+#define IS_BB_REG_OFFSET_92S(_Offset)  \
+       ((_Offset >= 0x800) && (_Offset <= 0xfff))
+
+#define        BRFMOD                                          0x1
+#define        BJAPANMODE                                      0x2
+#define        BCCKTXSC                                        0x30
+/* Block & Path enable*/
+#define ROFDMCCKEN                                     0x808
+#define        BCCKEN                                          0x10000000
+#define        BOFDMEN                                         0x20000000
+#define        RRXPATH                                         0x808   /* Rx antenna*/
+#define        BRXPATH                                         0xff
+#define        RTXPATH                                         0x80c   /* Tx antenna*/
+#define        BTXPATH                                         0x0fffffff
+#define        RCCK_RX                                         0xa04   /* for cck rx path selection*/
+#define        BCCK_RX                                         0x0c000000
+#define        RVHTLEN_USE_LSIG                        0x8c3   /* Use LSIG for VHT length*/
+
+
+#define        BOFDMRXADCPHASE                 0x10000
+#define        BOFDMTXDACPHASE                 0x40000
+#define        BXATXAGC                        0x3f
+
+#define        BXBTXAGC                        0xf00
+#define        BXCTXAGC                        0xf000
+#define        BXDTXAGC                        0xf0000
+
+#define        BPASTART                        0xf0000000
+#define        BTRSTART                        0x00f00000
+#define        BRFSTART                        0x0000f000
+#define        BBBSTART                        0x000000f0
+#define        BBBCCKSTART                     0x0000000f
+#define        BPAEND                          0xf
+#define        BTREND                          0x0f000000
+#define        BRFEND                          0x000f0000
+#define        BCCAMASK                        0x000000f0
+#define        BR2RCCAMASK                     0x00000f00
+#define        BHSSI_R2TDELAY                  0xf8000000
+#define        BHSSI_T2RDELAY                  0xf80000
+#define        BCONTXHSSI                      0x400
+#define        BIGFROMCCK                      0x200
+#define        BAGCADDRESS                     0x3f
+#define        BRXHPTX                         0x7000
+#define        BRXHP2RX                        0x38000
+#define        BRXHPCCKINI                     0xc0000
+#define        BAGCTXCODE                      0xc00000
+#define        BAGCRXCODE                      0x300000
+
+#define        B3WIREDATALENGTH                0x800
+#define        B3WIREADDREAALENGTH             0x400
+
+#define        B3WIRERFPOWERDOWN               0x1
+#define        B5GPAPEPOLARITY                 0x40000000
+#define        B2GPAPEPOLARITY                 0x80000000
+#define        BRFSW_TXDEFAULTANT              0x3
+#define        BRFSW_TXOPTIONANT               0x30
+#define        BRFSW_RXDEFAULTANT              0x300
+#define        BRFSW_RXOPTIONANT               0x3000
+#define        BRFSI_3WIREDATA                 0x1
+#define        BRFSI_3WIRECLOCK                0x2
+#define        BRFSI_3WIRELOAD                 0x4
+#define        BRFSI_3WIRERW                   0x8
+#define        BRFSI_3WIRE                     0xf
+
+#define        BRFSI_RFENV                     0x10
+
+#define        BRFSI_TRSW                      0x20
+#define        BRFSI_TRSWB                     0x40
+#define        BRFSI_ANTSW                     0x100
+#define        BRFSI_ANTSWB                    0x200
+#define        BRFSI_PAPE                      0x400
+#define        BRFSI_PAPE5G                    0x800
+#define        BBANDSELECT                     0x1
+#define        BHTSIG2_GI                      0x80
+#define        BHTSIG2_SMOOTHING               0x01
+#define        BHTSIG2_SOUNDING                0x02
+#define        BHTSIG2_AGGREATON               0x08
+#define        BHTSIG2_STBC                    0x30
+#define        BHTSIG2_ADVCODING               0x40
+#define        BHTSIG2_NUMOFHTLTF              0x300
+#define        BHTSIG2_CRC8                    0x3fc
+#define        BHTSIG1_MCS                     0x7f
+#define        BHTSIG1_BANDWIDTH               0x80
+#define        BHTSIG1_HTLENGTH                0xffff
+#define        BLSIG_RATE                      0xf
+#define        BLSIG_RESERVED                  0x10
+#define        BLSIG_LENGTH                    0x1fffe
+#define        BLSIG_PARITY                    0x20
+#define        BCCKRXPHASE                     0x4
+
+#define        BLSSIREADADDRESS                0x7f800000
+#define        BLSSIREADEDGE                   0x80000000
+
+#define        BLSSIREADBACKDATA               0xfffff
+
+#define        BLSSIREADOKFLAG                 0x1000
+#define        BCCKSAMPLERATE                  0x8
+#define        BREGULATOR0STANDBY              0x1
+#define        BREGULATORPLLSTANDBY            0x2
+#define        BREGULATOR1STANDBY              0x4
+#define        BPLLPOWERUP                     0x8
+#define        BDPLLPOWERUP                    0x10
+#define        BDA10POWERUP                    0x20
+#define        BAD7POWERUP                     0x200
+#define        BDA6POWERUP                     0x2000
+#define        BXTALPOWERUP                    0x4000
+#define        B40MDCLKPOWERUP                 0x8000
+#define        BDA6DEBUGMODE                   0x20000
+#define        BDA6SWING                       0x380000
+
+#define        BADCLKPHASE                     0x4000000
+#define        B80MCLKDELAY                    0x18000000
+#define        BAFEWATCHDOGENABLE              0x20000000
+
+#define        BXTALCAP01                      0xc0000000
+#define        BXTALCAP23                      0x3
+#define        BXTALCAP92X                                     0x0f000000
+#define BXTALCAP                       0x0f000000
+
+#define        BINTDIFCLKENABLE                0x400
+#define        BEXTSIGCLKENABLE                0x800
+#define        BBANDGAP_MBIAS_POWERUP      0x10000
+#define        BAD11SH_GAIN                    0xc0000
+#define        BAD11NPUT_RANGE                 0x700000
+#define        BAD110P_CURRENT                 0x3800000
+#define        BLPATH_LOOPBACK                 0x4000000
+#define        BQPATH_LOOPBACK                 0x8000000
+#define        BAFE_LOOPBACK                   0x10000000
+#define        BDA10_SWING                     0x7e0
+#define        BDA10_REVERSE                   0x800
+#define        BDA_CLK_SOURCE              0x1000
+#define        BDA7INPUT_RANGE                 0x6000
+#define        BDA7_GAIN                       0x38000
+#define        BDA7OUTPUT_CM_MODE          0x40000
+#define        BDA7INPUT_CM_MODE           0x380000
+#define        BDA7CURRENT                     0xc00000
+#define        BREGULATOR_ADJUST               0x7000000
+#define        BAD11POWERUP_ATTX               0x1
+#define        BDA10PS_ATTX                    0x10
+#define        BAD11POWERUP_ATRX               0x100
+#define        BDA10PS_ATRX                    0x1000
+#define        BCCKRX_AGC_FORMAT           0x200
+#define        BPSDFFT_SAMPLE_POINT            0xc000
+#define        BPSD_AVERAGE_NUM            0x3000
+#define        BIQPATH_CONTROL                 0xc00
+#define        BPSD_FREQ                       0x3ff
+#define        BPSD_ANTENNA_PATH           0x30
+#define        BPSD_IQ_SWITCH              0x40
+#define        BPSD_RX_TRIGGER             0x400000
+#define        BPSD_TX_TRIGGER             0x80000000
+#define        BPSD_SINE_TONE_SCALE        0x7f000000
+#define        BPSD_REPORT                     0xffff
+
+#define        BOFDM_TXSC                      0x30000000
+#define        BCCK_TXON                       0x1
+#define        BOFDM_TXON                      0x2
+#define        BDEBUG_PAGE                     0xfff
+#define        BDEBUG_ITEM                     0xff
+#define        BANTL                           0x10
+#define        BANT_NONHT                  0x100
+#define        BANT_HT1                        0x1000
+#define        BANT_HT2                        0x10000
+#define        BANT_HT1S1                      0x100000
+#define        BANT_NONHTS1                    0x1000000
+
+#define        BCCK_BBMODE                     0x3
+#define        BCCK_TXPOWERSAVING              0x80
+#define        BCCK_RXPOWERSAVING              0x40
+
+#define        BCCK_SIDEBAND                   0x10
+
+#define        BCCK_SCRAMBLE                   0x8
+#define        BCCK_ANTDIVERSITY               0x8000
+#define        BCCK_CARRIER_RECOVERY           0x4000
+#define        BCCK_TXRATE                     0x3000
+#define        BCCK_DCCANCEL                   0x0800
+#define        BCCK_ISICANCEL                  0x0400
+#define        BCCK_MATCH_FILTER           0x0200
+#define        BCCK_EQUALIZER                  0x0100
+#define        BCCK_PREAMBLE_DETECT            0x800000
+#define        BCCK_FAST_FALSECCA          0x400000
+#define        BCCK_CH_ESTSTART            0x300000
+#define        BCCK_CCA_COUNT              0x080000
+#define        BCCK_CS_LIM                     0x070000
+#define        BCCK_BIST_MODE              0x80000000
+#define        BCCK_CCAMASK                    0x40000000
+#define        BCCK_TX_DAC_PHASE               0x4
+#define        BCCK_RX_ADC_PHASE               0x20000000
+#define        BCCKR_CP_MODE                   0x0100
+#define        BCCK_TXDC_OFFSET                0xf0
+#define        BCCK_RXDC_OFFSET                0xf
+#define        BCCK_CCA_MODE                   0xc000
+#define        BCCK_FALSECS_LIM                0x3f00
+#define        BCCK_CS_RATIO                   0xc00000
+#define        BCCK_CORGBIT_SEL                0x300000
+#define        BCCK_PD_LIM                     0x0f0000
+#define        BCCK_NEWCCA                     0x80000000
+#define        BCCK_RXHP_OF_IG             0x8000
+#define        BCCK_RXIG                       0x7f00
+#define        BCCK_LNA_POLARITY           0x800000
+#define        BCCK_RX1ST_BAIN             0x7f0000
+#define        BCCK_RF_EXTEND              0x20000000
+#define        BCCK_RXAGC_SATLEVEL             0x1f000000
+#define        BCCK_RXAGC_SATCOUNT             0xe0
+#define        bCCKRxRFSettle                  0x1f
+#define        BCCK_FIXED_RXAGC                0x8000
+#define        BCCK_ANTENNA_POLARITY           0x2000
+#define        BCCK_TXFILTER_TYPE          0x0c00
+#define        BCCK_RXAGC_REPORTTYPE           0x0300
+#define        BCCK_RXDAGC_EN              0x80000000
+#define        BCCK_RXDAGC_PERIOD              0x20000000
+#define        BCCK_RXDAGC_SATLEVEL            0x1f000000
+#define        BCCK_TIMING_RECOVERY            0x800000
+#define        BCCK_TXC0                       0x3f0000
+#define        BCCK_TXC1                       0x3f000000
+#define        BCCK_TXC2                       0x3f
+#define        BCCK_TXC3                       0x3f00
+#define        BCCK_TXC4                       0x3f0000
+#define        BCCK_TXC5                       0x3f000000
+#define        BCCK_TXC6                       0x3f
+#define        BCCK_TXC7                       0x3f00
+#define        BCCK_DEBUGPORT                  0xff0000
+#define        BCCK_DAC_DEBUG              0x0f000000
+#define        BCCK_FALSEALARM_ENABLE      0x8000
+#define        BCCK_FALSEALARM_READ        0x4000
+#define        BCCK_TRSSI                      0x7f
+#define        BCCK_RXAGC_REPORT           0xfe
+#define        BCCK_RXREPORT_ANTSEL            0x80000000
+#define        BCCK_RXREPORT_MFOFF             0x40000000
+#define        BCCK_RXREPORT_SQLOSS            0x20000000
+#define        BCCK_RXREPORT_PKTLOSS           0x10000000
+#define        BCCK_RXREPORT_LOCKEDBIT         0x08000000
+#define        BCCK_RXREPORT_RATEERROR         0x04000000
+#define        BCCK_RXREPORT_RXRATE            0x03000000
+#define        BCCK_RXFA_COUNTER_LOWER     0xff
+#define        BCCK_RXFA_COUNTER_UPPER     0xff000000
+#define        BCCK_RXHPAGC_START          0xe000
+#define        BCCK_RXHPAGC_FINAL          0x1c00
+#define        BCCK_RXFALSEALARM_ENABLE    0x8000
+#define        BCCK_FACOUNTER_FREEZE       0x4000
+#define        BCCK_TXPATH_SEL             0x10000000
+#define        BCCK_DEFAULT_RXPATH         0xc000000
+#define        BCCK_OPTION_RXPATH          0x3000000
+
+#define        BNUM_OFSTF                      0x3
+#define        BSHIFT_L                        0xc0
+#define        BGI_TH                          0xc
+#define        BRXPATH_A                       0x1
+#define        BRXPATH_B                       0x2
+#define        BRXPATH_C                       0x4
+#define        BRXPATH_D                       0x8
+#define        BTXPATH_A                       0x1
+#define        BTXPATH_B                       0x2
+#define        BTXPATH_C                       0x4
+#define        BTXPATH_D                       0x8
+#define        BTRSSI_FREQ                     0x200
+#define        BADC_BACKOFF                    0x3000
+#define        BDFIR_BACKOFF                   0xc000
+#define        BTRSSI_LATCH_PHASE              0x10000
+#define        BRX_LDC_OFFSET                  0xff
+#define        BRX_QDC_OFFSET                  0xff00
+#define        BRX_DFIR_MODE                   0x1800000
+#define        BRX_DCNF_TYPE                   0xe000000
+#define        BRXIQIMB_A                      0x3ff
+#define        BRXIQIMB_B                      0xfc00
+#define        BRXIQIMB_C                      0x3f0000
+#define        BRXIQIMB_D                      0xffc00000
+#define        BDC_DC_NOTCH                    0x60000
+#define        BRXNB_NOTCH                     0x1f000000
+#define        BPD_TH                          0xf
+#define        BPD_TH_OPT2                     0xc000
+#define        BPWED_TH                        0x700
+#define        BIFMF_WIN_L                     0x800
+#define        BPD_OPTION                      0x1000
+#define        BMF_WIN_L                       0xe000
+#define        BBW_SEARCH_L                    0x30000
+#define        BWIN_ENH_L                      0xc0000
+#define        BBW_TH                          0x700000
+#define        BED_TH2                         0x3800000
+#define        BBW_OPTION                      0x4000000
+#define        BRADIO_TH                       0x18000000
+#define        BWINDOW_L                       0xe0000000
+#define        BSBD_OPTION                     0x1
+#define        BFRAME_TH                       0x1c
+#define        BFS_OPTION                      0x60
+#define        BDC_SLOPE_CHECK                 0x80
+#define        BFGUARD_COUNTER_DC_L            0xe00
+#define        BFRAME_WEIGHT_SHORT             0x7000
+#define        BSUB_TUNE                       0xe00000
+#define        BFRAME_DC_LENGTH                0xe000000
+#define        BSBD_START_OFFSET               0x30000000
+#define        BFRAME_TH_2                     0x7
+#define        BFRAME_GI2_TH                   0x38
+#define        BGI2_SYNC_EN                    0x40
+#define        BSARCH_SHORT_EARLY              0x300
+#define        BSARCH_SHORT_LATE               0xc00
+#define        BSARCH_GI2_LATE                 0x70000
+#define        BCFOANTSUM                      0x1
+#define        BCFOACC                         0x2
+#define        BCFOSTARTOFFSET                 0xc
+#define        BCFOLOOPBACK                    0x70
+#define        BCFOSUMWEIGHT                   0x80
+#define        BDAGCENABLE                     0x10000
+#define        BTXIQIMB_A                      0x3ff
+#define        BTXIQIMB_b                      0xfc00
+#define        BTXIQIMB_C                      0x3f0000
+#define        BTXIQIMB_D                      0xffc00000
+#define        BTXIDCOFFSET                    0xff
+#define        BTXIQDCOFFSET                   0xff00
+#define        BTXDFIRMODE                     0x10000
+#define        BTXPESUDO_NOISEON               0x4000000
+#define        BTXPESUDO_NOISE_A               0xff
+#define        BTXPESUDO_NOISE_B               0xff00
+#define        BTXPESUDO_NOISE_C               0xff0000
+#define        BTXPESUDO_NOISE_D               0xff000000
+#define        BCCA_DROPOPTION                 0x20000
+#define        BCCA_DROPTHRES                  0xfff00000
+#define        BEDCCA_H                        0xf
+#define        BEDCCA_L                        0xf0
+#define        BLAMBDA_ED                      0x300
+#define        BRX_INITIALGAIN                 0x7f
+#define        BRX_ANTDIV_EN                   0x80
+#define        BRX_AGC_ADDRESS_FOR_LNA     0x7f00
+#define        BRX_HIGHPOWER_FLOW              0x8000
+#define        BRX_AGC_FREEZE_THRES        0xc0000
+#define        BRX_FREEZESTEP_AGC1             0x300000
+#define        BRX_FREEZESTEP_AGC2             0xc00000
+#define        BRX_FREEZESTEP_AGC3             0x3000000
+#define        BRX_FREEZESTEP_AGC0             0xc000000
+#define        BRXRSSI_CMP_EN                  0x10000000
+#define        BRXQUICK_AGCEN                  0x20000000
+#define        BRXAGC_FREEZE_THRES_MODE    0x40000000
+#define        BRX_OVERFLOW_CHECKTYPE          0x80000000
+#define        BRX_AGCSHIFT                    0x7f
+#define        BTRSW_TRI_ONLY                  0x80
+#define        BPOWER_THRES                    0x300
+#define        BRXAGC_EN                       0x1
+#define        BRXAGC_TOGETHER_EN              0x2
+#define        BRXAGC_MIN                      0x4
+#define        BRXHP_INI                       0x7
+#define        BRXHP_TRLNA                     0x70
+#define        BRXHP_RSSI                      0x700
+#define        BRXHP_BBP1                      0x7000
+#define        BRXHP_BBP2                      0x70000
+#define        BRXHP_BBP3                      0x700000
+#define        BRSSI_H                         0x7f0000
+#define        BRSSI_GEN                       0x7f000000
+#define        BRXSETTLE_TRSW                  0x7
+#define        BRXSETTLE_LNA                   0x38
+#define        BRXSETTLE_RSSI                  0x1c0
+#define        BRXSETTLE_BBP                   0xe00
+#define        BRXSETTLE_RXHP                  0x7000
+#define        BRXSETTLE_ANTSW_RSSI            0x38000
+#define        BRXSETTLE_ANTSW                 0xc0000
+#define        BRXPROCESS_TIME_DAGC            0x300000
+#define        BRXSETTLE_HSSI                  0x400000
+#define        BRXPROCESS_TIME_BBPPW           0x800000
+#define        BRXANTENNA_POWER_SHIFT          0x3000000
+#define        BRSSI_TABLE_SELECT              0xc000000
+#define        BRXHP_FINAL                     0x7000000
+#define        BRXHPSETTLE_BBP                 0x7
+#define        BRXHTSETTLE_HSSI                0x8
+#define        BRXHTSETTLE_RXHP                0x70
+#define        BRXHTSETTLE_BBPPW               0x80
+#define        BRXHTSETTLE_IDLE                0x300
+#define        BRXHTSETTLE_RESERVED            0x1c00
+#define        BRXHT_RXHP_EN                   0x8000
+#define        BRXAGC_FREEZE_THRES             0x30000
+#define        BRXAGC_TOGETHEREN               0x40000
+#define        BRXHTAGC_MIN                    0x80000
+#define        BRXHTAGC_EN                     0x100000
+#define        BRXHTDAGC_EN                    0x200000
+#define        BRXHT_RXHP_BBP                  0x1c00000
+#define        BRXHT_RXHP_FINAL                0xe0000000
+#define        BRXPW_RADIO_TH                  0x3
+#define        BRXPW_RADIO_EN                  0x4
+#define        BRXMF_HOLD                      0x3800
+#define        BRXPD_DELAY_TH1                 0x38
+#define        BRXPD_DELAY_TH2                 0x1c0
+#define        BRXPD_DC_COUNT_MAX              0x600
+#define        BRXPD_DELAY_TH                  0x8000
+#define        BRXPROCESS_DELAY                0xf0000
+#define        BRXSEARCHRANGE_GI2_EARLY        0x700000
+#define        BRXFRAME_FUARD_COUNTER_L        0x3800000
+#define        BRXSGI_GUARD_L                  0xc000000
+#define        BRXSGI_SEARCH_L                 0x30000000
+#define        BRXSGI_TH                       0xc0000000
+#define        BDFSCNT0                        0xff
+#define        BDFSCNT1                        0xff00
+#define        BDFSFLAG                        0xf0000
+#define        BMF_WEIGHT_SUM                  0x300000
+#define        BMINIDX_TH                      0x7f000000
+#define        BDAFORMAT                       0x40000
+#define        BTXCH_EMU_ENABLE                0x01000000
+#define        BTRSW_ISOLATION_A               0x7f
+#define        BTRSW_ISOLATION_B               0x7f00
+#define        BTRSW_ISOLATION_C               0x7f0000
+#define        BTRSW_ISOLATION_D               0x7f000000
+#define        BEXT_LNA_GAIN                   0x7c00
+
+#define        BSTBC_EN                        0x4
+#define        BANTENNA_MAPPING                0x10
+#define        BNSS                            0x20
+#define        BCFO_ANTSUM_ID              0x200
+#define        BPHY_COUNTER_RESET              0x8000000
+#define        BCFO_REPORT_GET                 0x4000000
+#define        BOFDM_CONTINUE_TX               0x10000000
+#define        BOFDM_SINGLE_CARRIER            0x20000000
+#define        BOFDM_SINGLE_TONE               0x40000000
+#define        BHT_DETECT                      0x100
+#define        BCFOEN                          0x10000
+#define        BCFOVALUE                       0xfff00000
+#define        BSIGTONE_RE                     0x3f
+#define        BSIGTONE_IM                     0x7f00
+#define        BCOUNTER_CCA                    0xffff
+#define        BCOUNTER_PARITYFAIL             0xffff0000
+#define        BCOUNTER_RATEILLEGAL            0xffff
+#define        BCOUNTER_CRC8FAIL               0xffff0000
+#define        BCOUNTER_MCSNOSUPPORT           0xffff
+#define        BCOUNTER_FASTSYNC               0xffff
+#define        BSHORTCFO                       0xfff
+#define        BSHORTCFOT_LENGTH               12
+#define        BSHORTCFOF_LENGTH               11
+#define        BLONGCFO                        0x7ff
+#define        BLONGCFOT_LENGTH                11
+#define        BLONGCFOF_LENGTH                11
+#define        BTAILCFO                        0x1fff
+#define        BTAILCFOT_LENGTH                13
+#define        BTAILCFOF_LENGTH                12
+#define        BNOISE_EN_PWDB                  0xffff
+#define        BCC_POWER_DB                    0xffff0000
+#define        BMOISE_PWDB                     0xffff
+#define        BPOWERMEAST_LENGTH              10
+#define        BPOWERMEASF_LENGTH              3
+#define        BRX_HT_BW                       0x1
+#define        BRXSC                           0x6
+#define        BRX_HT                          0x8
+#define        BNB_INTF_DET_ON                 0x1
+#define        BINTF_WIN_LEN_CFG               0x30
+#define        BNB_INTF_TH_CFG                 0x1c0
+#define        BRFGAIN                         0x3f
+#define        BTABLESEL                       0x40
+#define        BTRSW                           0x80
+#define        BRXSNR_A                        0xff
+#define        BRXSNR_B                        0xff00
+#define        BRXSNR_C                        0xff0000
+#define        BRXSNR_D                        0xff000000
+#define        BSNR_EVMT_LENGTH                8
+#define        BSNR_EVMF_LENGTH                1
+#define        BCSI1ST                         0xff
+#define        BCSI2ND                         0xff00
+#define        BRXEVM1ST                       0xff0000
+#define        BRXEVM2ND                       0xff000000
+#define        BSIGEVM                         0xff
+#define        BPWDB                           0xff00
+#define        BSGIEN                          0x10000
+
+#define        BSFACTOR_QMA1                   0xf
+#define        BSFACTOR_QMA2                   0xf0
+#define        BSFACTOR_QMA3                   0xf00
+#define        BSFACTOR_QMA4                   0xf000
+#define        BSFACTOR_QMA5                   0xf0000
+#define        BSFACTOR_QMA6                   0xf0000
+#define        BSFACTOR_QMA7                   0xf00000
+#define        BSFACTOR_QMA8                   0xf000000
+#define        BSFACTOR_QMA9                   0xf0000000
+#define        BCSI_SCHEME                     0x100000
+
+#define        BNOISE_LVL_TOP_SET          0x3
+#define        BCHSMOOTH                       0x4
+#define        BCHSMOOTH_CFG1                  0x38
+#define        BCHSMOOTH_CFG2                  0x1c0
+#define        BCHSMOOTH_CFG3                  0xe00
+#define        BCHSMOOTH_CFG4                  0x7000
+#define        BMRCMODE                        0x800000
+#define        BTHEVMCFG                       0x7000000
+
+#define        BLOOP_FIT_TYPE                  0x1
+#define        BUPD_CFO                        0x40
+#define        BUPD_CFO_OFFDATA                0x80
+#define        BADV_UPD_CFO                    0x100
+#define        BADV_TIME_CTRL                  0x800
+#define        BUPD_CLKO                       0x1000
+#define        BFC                             0x6000
+#define        BTRACKING_MODE                  0x8000
+#define        BPHCMP_ENABLE                   0x10000
+#define        BUPD_CLKO_LTF                   0x20000
+#define        BCOM_CH_CFO                     0x40000
+#define        BCSI_ESTI_MODE                  0x80000
+#define        BADV_UPD_EQZ                    0x100000
+#define        BUCHCFG                         0x7000000
+#define        BUPDEQZ                         0x8000000
+
+#define        BRX_PESUDO_NOISE_ON         0x20000000
+#define        BRX_PESUDO_NOISE_A              0xff
+#define        BRX_PESUDO_NOISE_B              0xff00
+#define        BRX_PESUDO_NOISE_C              0xff0000
+#define        BRX_PESUDO_NOISE_D              0xff000000
+#define        BRX_PESUDO_NOISESTATE_A     0xffff
+#define        BRX_PESUDO_NOISESTATE_B     0xffff0000
+#define        BRX_PESUDO_NOISESTATE_C     0xffff
+#define        BRX_PESUDO_NOISESTATE_D     0xffff0000
+
+#define        BZEBRA1_HSSIENABLE              0x8
+#define        BZEBRA1_TRXCONTROL              0xc00
+#define        BZEBRA1_TRXGAINSETTING          0x07f
+#define        BZEBRA1_RXCOUNTER               0xc00
+#define        BZEBRA1_TXCHANGEPUMP            0x38
+#define        BZEBRA1_RXCHANGEPUMP            0x7
+#define        BZEBRA1_CHANNEL_NUM             0xf80
+#define        BZEBRA1_TXLPFBW                 0x400
+#define        BZEBRA1_RXLPFBW                 0x600
+
+#define        BRTL8256REG_MODE_CTRL1      0x100
+#define        BRTL8256REG_MODE_CTRL0      0x40
+#define        BRTL8256REG_TXLPFBW         0x18
+#define        BRTL8256REG_RXLPFBW         0x600
+
+#define        BRTL8258_TXLPFBW                0xc
+#define        BRTL8258_RXLPFBW                0xc00
+#define        BRTL8258_RSSILPFBW              0xc0
+
+#define        BBYTE0                          0x1
+#define        BBYTE1                          0x2
+#define        BBYTE2                          0x4
+#define        BBYTE3                          0x8
+#define        BWORD0                          0x3
+#define        BWORD1                          0xc
+#define        BWORD                           0xf
+
+#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
+
+#define        MASK4BITS                       0x0f
+#define        MASK20BITS                      0xfffff
+#define RFREG_OFFSET_MASK                      0xfffff
+
+#define        BENABLE                         0x1
+#define        BDISABLE                        0x0
+
+#define        LEFT_ANTENNA                    0x0
+#define        RIGHT_ANTENNA                   0x1
+
+#define        TCHECK_TXSTATUS                 500
+#define        TUPDATE_RXCOUNTER               100
+
+#define        REG_UN_used_register            0x01bf
+
+/* WOL bit information */
+#define        HAL92C_WOL_PTK_UPDATE_EVENT             BIT(0)
+#define        HAL92C_WOL_GTK_UPDATE_EVENT             BIT(1)
+#define        HAL92C_WOL_DISASSOC_EVENT               BIT(2)
+#define        HAL92C_WOL_DEAUTH_EVENT                 BIT(3)
+#define        HAL92C_WOL_FW_DISCONNECT_EVENT  BIT(4)
+
+#define                WOL_REASON_PTK_UPDATE           BIT(0)
+#define                WOL_REASON_GTK_UPDATE           BIT(1)
+#define                WOL_REASON_DISASSOC                     BIT(2)
+#define                WOL_REASON_DEAUTH                       BIT(3)
+#define                WOL_REASON_FW_DISCONNECT        BIT(4)
+
+#define                RA_RFE_PINMUX   0xcb0  /* Path_A RFE cotrol pinmux*/
+#define                RB_RFE_PINMUX   0xeb0 /* Path_B RFE control pinmux*/
+
+#define                RA_RFE_INV 0xcb4
+#define                RB_RFE_INV 0xeb4
+
+/* RXIQC */
+#define                RA_RXIQC_AB     0xc10  /*RxIQ imblance matrix coeff. A & B*/
+#define                RA_RXIQC_CD     0xc14  /*RxIQ imblance matrix coeff. C & D*/
+#define                RA_TXSCALE              0xc1c  /* Pah_A TX scaling factor*/
+#define                RB_TXSCALE              0xe1c  /* Path_B TX scaling factor*/
+#define                RB_RXIQC_AB     0xe10  /*RxIQ imblance matrix coeff. A & B*/
+#define                RB_RXIQC_CD     0xe14  /*RxIQ imblance matrix coeff. C & D*/
+#define                RXIQC_AC                0x02ff  /*bit mask for IQC matrix element A & C*/
+#define                RXIQC_BD                0x02ff0000 /*bit mask for IQC matrix element A & C*/
+
+/* 2 EFUSE_TEST (For RTL8723 partially) */
+#define EFUSE_SEL(x)                                   (((x) & 0x3) << 8)
+#define EFUSE_SEL_MASK                         0x300
+#define EFUSE_WIFI_SEL_0                               0x0
+
+/*REG_MULTI_FUNC_CTRL(For RTL8723 Only)*/
+#define        WL_HWPDN_EN                             BIT(0)  /* Enable GPIO[9] as WiFi HW PDn source*/
+#define        WL_HWPDN_SL                             BIT(1)  /* WiFi HW PDn polarity control*/
+#define        WL_FUNC_EN                              BIT(2)  // WiFi function enable
+#define        WL_HWROF_EN                             BIT(3)  // Enable GPIO[9] as WiFi RF HW PDn source
+#define        BT_HWPDN_EN                             BIT(16) // Enable GPIO[11] as BT HW PDn source
+#define        BT_HWPDN_SL                             BIT(17) // BT HW PDn polarity control
+#define        BT_FUNC_EN                              BIT(18) // BT function enable
+#define        BT_HWROF_EN                             BIT(19) // Enable GPIO[11] as BT/GPS RF HW PDn source
+#define        GPS_HWPDN_EN                            BIT(20) // Enable GPIO[10] as GPS HW PDn source
+#define        GPS_HWPDN_SL                            BIT(21) // GPS HW PDn polarity control
+#define        GPS_FUNC_EN                             BIT(22) // GPS function enable
+
+
+#define        BMASKBYTE0                      0xff
+#define        BMASKBYTE1                      0xff00
+#define        BMASKBYTE2                      0xff0000
+#define        BMASKBYTE3                      0xff000000
+#define        BMASKHWORD                      0xffff0000
+#define        BMASKLWORD                      0x0000ffff
+#define        BMASKDWORD                      0xffffffff
+#define        BMASK12BITS                                     0xfff
+#define        BMASKH4BITS                                     0xf0000000
+#define BMASKOFDM_D                                    0xffc00000
+#define        BMASKCCK                                        0x3f3f3f3f
+
+#define BRFREGOFFSETMASK                       0xfffff
+
+#define        ODM_REG_CCK_RPT_FORMAT_11AC     0x804
+#define        ODM_REG_BB_RX_PATH_11AC                 0x808
+/*PAGE 9*/
+#define        ODM_REG_OFDM_FA_RST_11AC                0x9A4
+/*PAGE A*/
+#define        ODM_REG_CCK_CCA_11AC                    0xA0A
+#define        ODM_REG_CCK_FA_RST_11AC                 0xA2C
+#define        ODM_REG_CCK_FA_11AC                             0xA5C
+/*PAGE C*/
+#define        ODM_REG_IGI_A_11AC                              0xC50
+/*PAGE E*/
+#define        ODM_REG_IGI_B_11AC                              0xE50
+/*PAGE F*/
+#define        ODM_REG_OFDM_FA_11AC                    0xF48
+
+
+//2 MAC REG LIST
+
+
+
+
+//DIG Related
+#define        ODM_BIT_IGI_11AC                                        0xFFFFFFFF
+#define        ODM_BIT_CCK_RPT_FORMAT_11AC             BIT16
+#define        ODM_BIT_BB_RX_PATH_11AC                 0xF
+
+typedef enum AGGRE_SIZE{
+       HT_AGG_SIZE_8K = 0,
+       HT_AGG_SIZE_16K = 1,
+       HT_AGG_SIZE_32K = 2,
+       HT_AGG_SIZE_64K = 3,
+       VHT_AGG_SIZE_128K = 4,
+       VHT_AGG_SIZE_256K = 5,
+       VHT_AGG_SIZE_512K = 6,
+       VHT_AGG_SIZE_1024K = 7,
+}AGGRE_SIZE_E, *PAGGRE_SIZE_E;
+
+#define REG_AMPDU_MAX_LENGTH_8812      0x0458
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/rf.c b/drivers/staging/rtl8821ae/rtl8821ae/rf.c
new file mode 100644 (file)
index 0000000..87c1c97
--- /dev/null
@@ -0,0 +1,464 @@
+/******************************************************************************
+ *
+ * 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 "../wifi.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+
+static bool _rtl8821ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
+
+void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       switch (bandwidth) {
+       case HT_CHANNEL_WIDTH_20:
+               rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, BIT(11)|BIT(10), 3);
+               rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, BIT(11)|BIT(10), 3);
+               break;
+       case HT_CHANNEL_WIDTH_20_40:
+               rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, BIT(11)|BIT(10), 1);
+               rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, BIT(11)|BIT(10), 1);
+               break;
+       case HT_CHANNEL_WIDTH_80:
+               rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, BIT(11)|BIT(10), 0);
+               rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, BIT(11)|BIT(10), 0);
+               break;
+       default:
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("unknown bandwidth: %#X\n", bandwidth));
+               break;
+       }
+}
+
+void rtl8821ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+                                      u8 *ppowerlevel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u32 tx_agc[2] = {0, 0}, tmpval;
+       bool turbo_scanoff = false;
+       u8 idx1, idx2;
+       u8 *ptr;
+       u8 direction;
+       u32 pwrtrac_value;
+
+       if (rtlefuse->eeprom_regulatory != 0)
+               turbo_scanoff = true;
+
+       if (mac->act_scanning == true) {
+               tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
+               tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
+
+               if (turbo_scanoff) {
+                       for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+                               tx_agc[idx1] = ppowerlevel[idx1] |
+                                   (ppowerlevel[idx1] << 8) |
+                                   (ppowerlevel[idx1] << 16) |
+                                   (ppowerlevel[idx1] << 24);
+                       }
+               }
+       } else {
+               for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+                       tx_agc[idx1] = ppowerlevel[idx1] |
+                           (ppowerlevel[idx1] << 8) |
+                           (ppowerlevel[idx1] << 16) |
+                           (ppowerlevel[idx1] << 24);
+               }
+
+               if (rtlefuse->eeprom_regulatory == 0) {
+                       tmpval =
+                           (rtlphy->mcs_txpwrlevel_origoffset[0][6]) +
+                           (rtlphy->mcs_txpwrlevel_origoffset[0][7] <<
+                            8);
+                       tx_agc[RF90_PATH_A] += tmpval;
+
+                       tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
+                           (rtlphy->mcs_txpwrlevel_origoffset[0][15] <<
+                            24);
+                       tx_agc[RF90_PATH_B] += tmpval;
+               }
+       }
+
+       for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+               ptr = (u8 *) (&(tx_agc[idx1]));
+               for (idx2 = 0; idx2 < 4; idx2++) {
+                       if (*ptr > RF6052_MAX_TX_PWR)
+                               *ptr = RF6052_MAX_TX_PWR;
+                       ptr++;
+               }
+       }
+       rtl8821ae_dm_txpower_track_adjust(hw,1,&direction,&pwrtrac_value);
+       if (direction ==1){
+               tx_agc[0] += pwrtrac_value;
+               tx_agc[1] += pwrtrac_value;
+       } else if (direction == 2){
+               tx_agc[0] -= pwrtrac_value;
+               tx_agc[1] -= pwrtrac_value;
+       }
+       tmpval = tx_agc[RF90_PATH_A] ;
+       rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, MASKDWORD, tmpval);
+
+       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+               ("CCK PWR 1~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
+                RTXAGC_A_CCK11_CCK1));
+
+       tmpval = tx_agc[RF90_PATH_B] ;
+       rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, MASKDWORD, tmpval);
+
+       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+               ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
+                RTXAGC_B_CCK11_CCK1));
+}
+
+static void rtl8821ae_phy_get_power_base(struct ieee80211_hw *hw,
+                                     u8 *ppowerlevel_ofdm, u8 *ppowerlevel_bw20, u8 *ppowerlevel_bw40, u8 channel,
+                                     u32 *ofdmbase, u32 *mcsbase)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u32 powerBase0, powerBase1;
+       u8 i, powerlevel[2];
+
+       for (i = 0; i < 2; i++) {
+               powerBase0 = ppowerlevel_ofdm[i];
+
+               powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
+                   (powerBase0 << 8) | powerBase0;
+               *(ofdmbase + i) = powerBase0;
+               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                       (" [OFDM power base index rf(%c) = 0x%x]\n",
+                        ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+       }
+
+       for (i = 0; i < 2; i++) {
+               if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
+                       powerlevel[i] = ppowerlevel_bw20[i];
+               }else{
+                       powerlevel[i] = ppowerlevel_bw40[i];
+               }
+               powerBase1 = powerlevel[i];
+               powerBase1 = (powerBase1 << 24) |
+                   (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
+
+               *(mcsbase + i) = powerBase1;
+
+               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                       (" [MCS power base index rf(%c) = 0x%x]\n",
+                        ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+       }
+}
+
+static void _rtl8821ae_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
+                                                      u8 channel, u8 index,
+                                                      u32 *powerBase0,
+                                                      u32 *powerBase1,
+                                                      u32 *p_outwriteval)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 i, chnlgroup = 0, pwr_diff_limit[4],pwr_diff = 0,customer_pwr_diff;
+       u32 writeVal, customer_limit, rf;
+
+       for (rf = 0; rf < 2; rf++) {
+               switch (rtlefuse->eeprom_regulatory) {
+               case 0:
+                       chnlgroup = 0;
+
+                       writeVal =
+                           rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index +
+                                                                        (rf ? 8 : 0)]
+                           + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
+
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("RTK better performance, "
+                                "writeVal(%c) = 0x%x\n",
+                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                       break;
+               case 1:
+                       if (rtlphy->pwrgroup_cnt == 1)
+                               chnlgroup = 0;
+                       else {
+                               if(channel<3)
+                                       chnlgroup = 0;
+                               else if (channel <6)
+                                       chnlgroup = 1;
+                               else if (channel <9)
+                                       chnlgroup = 2;
+                               else if (channel <12)
+                                       chnlgroup = 3;
+                               else if (channel < 14)
+                                       chnlgroup = 4;
+                               else if (channel == 14)
+                                       chnlgroup = 5;
+                       }
+
+                       writeVal =
+                           rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
+                           [index + (rf ? 8 : 0)] + ((index < 2) ?
+                                                     powerBase0[rf] :
+                                                     powerBase1[rf]);
+
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("Realtek regulatory, 20MHz, "
+                                "writeVal(%c) = 0x%x\n",
+                                ((rf == 0) ? 'A' : 'B'), writeVal));
+
+                       break;
+               case 2:
+                       writeVal =
+                           ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
+
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("Better regulatory, "
+                                "writeVal(%c) = 0x%x\n",
+                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                       break;
+               case 3:
+                       chnlgroup = 0;
+
+                       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+                               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                                       ("customer's limit, 40MHz "
+                                        "rf(%c) = 0x%x\n",
+                                        ((rf == 0) ? 'A' : 'B'),
+                                        rtlefuse->pwrgroup_ht40[rf][channel -
+                                                                    1]));
+                       } else {
+                               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                                       ("customer's limit, 20MHz "
+                                        "rf(%c) = 0x%x\n",
+                                        ((rf == 0) ? 'A' : 'B'),
+                                        rtlefuse->pwrgroup_ht20[rf][channel -
+                                                                    1]));
+                       }
+
+                       if (index < 2)
+                               pwr_diff = rtlefuse->txpwr_legacyhtdiff[rf][channel-1];
+                       else if (rtlphy->current_chan_bw ==  HT_CHANNEL_WIDTH_20)
+                               pwr_diff = rtlefuse->txpwr_ht20diff[rf][channel-1];
+
+                       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
+                               customer_pwr_diff = rtlefuse->pwrgroup_ht40[rf][channel-1];
+                       else
+                               customer_pwr_diff = rtlefuse->pwrgroup_ht20[rf][channel-1];
+
+                       if (pwr_diff > customer_pwr_diff)
+                               pwr_diff = 0;
+                       else
+                               pwr_diff = customer_pwr_diff - pwr_diff;
+
+                       for (i = 0; i < 4; i++) {
+                               pwr_diff_limit[i] =
+                                   (u8) ((rtlphy->mcs_txpwrlevel_origoffset
+                                          [chnlgroup][index + (rf ? 8 : 0)] & (0x7f <<
+                                                                       (i * 8))) >> (i * 8));
+
+                                       if(pwr_diff_limit[i] > pwr_diff)
+                                               pwr_diff_limit[i] = pwr_diff;
+                       }
+
+                       customer_limit = (pwr_diff_limit[3] << 24) |
+                           (pwr_diff_limit[2] << 16) |
+                           (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
+
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("Customer's limit rf(%c) = 0x%x\n",
+                                ((rf == 0) ? 'A' : 'B'), customer_limit));
+
+                       writeVal = customer_limit +
+                           ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
+
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("Customer, writeVal rf(%c)= 0x%x\n",
+                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                       break;
+               default:
+                       chnlgroup = 0;
+                       writeVal =
+                           rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
+                           [index + (rf ? 8 : 0)]
+                           + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
+
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("RTK better performance, writeVal "
+                                "rf(%c) = 0x%x\n",
+                                ((rf == 0) ? 'A' : 'B'), writeVal));
+                       break;
+               }
+
+               if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
+                       writeVal = writeVal - 0x06060606;
+               else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+                        TXHIGHPWRLEVEL_BT2)
+                       writeVal = writeVal - 0x0c0c0c0c;
+               *(p_outwriteval + rf) = writeVal;
+       }
+}
+
+static void _rtl8821ae_write_ofdm_power_reg(struct ieee80211_hw *hw,
+                                        u8 index, u32 *pValue)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u16 regoffset_a[6] = {
+               RTXAGC_A_OFDM18_OFDM6, RTXAGC_A_OFDM54_OFDM24,
+               RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
+               RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
+       };
+       u16 regoffset_b[6] = {
+               RTXAGC_B_OFDM18_OFDM6, RTXAGC_B_OFDM54_OFDM24,
+               RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
+               RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
+       };
+       u8 i, rf, pwr_val[4];
+       u32 writeVal;
+       u16 regoffset;
+
+       for (rf = 0; rf < 2; rf++) {
+               writeVal = pValue[rf];
+               for (i = 0; i < 4; i++) {
+                       pwr_val[i] = (u8) ((writeVal & (0x7f <<
+                                                       (i * 8))) >> (i * 8));
+
+                       if (pwr_val[i] > RF6052_MAX_TX_PWR)
+                               pwr_val[i] = RF6052_MAX_TX_PWR;
+               }
+               writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
+                   (pwr_val[1] << 8) | pwr_val[0];
+
+               if (rf == 0)
+                       regoffset = regoffset_a[index];
+               else
+                       regoffset = regoffset_b[index];
+               rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
+
+               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                       ("Set 0x%x = %08x\n", regoffset, writeVal));
+       }
+}
+
+void rtl8821ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+                                             u8 *ppowerlevel_ofdm, u8 *ppowerlevel_bw20, u8 *ppowerlevel_bw40, u8 channel)
+{
+       u32 writeVal[2], powerBase0[2], powerBase1[2];
+       u8 index;
+       u8 direction;
+       u32 pwrtrac_value;
+
+       rtl8821ae_phy_get_power_base(hw, ppowerlevel_ofdm, ppowerlevel_bw20, ppowerlevel_bw40,
+                                 channel, &powerBase0[0], &powerBase1[0]);
+
+       rtl8821ae_dm_txpower_track_adjust(hw,1,&direction,&pwrtrac_value);
+
+       for (index = 0; index < 6; index++) {
+               _rtl8821ae_get_txpower_writeval_by_regulatory(hw,
+                                                          channel, index,
+                                                          &powerBase0[0],
+                                                          &powerBase1[0],
+                                                          &writeVal[0]);
+               if (direction ==1){
+                       writeVal[0] += pwrtrac_value;
+                       writeVal[1] += pwrtrac_value;
+               } else if (direction == 2){
+                       writeVal[0] -= pwrtrac_value;
+                       writeVal[1] -= pwrtrac_value;
+               }
+               _rtl8821ae_write_ofdm_power_reg(hw, index, &writeVal[0]);
+       }
+}
+
+bool rtl8821ae_phy_rf6052_config(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       if (rtlphy->rf_type == RF_1T1R)
+               rtlphy->num_total_rfpath = 1;
+       else
+               rtlphy->num_total_rfpath = 2;
+
+       return _rtl8821ae_phy_rf6052_config_parafile(hw);
+
+}
+
+static bool _rtl8821ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       //u32 u4_regvalue = 0;
+       u8 rfpath;
+       bool rtstatus = true;
+       //struct bb_reg_def *pphyreg;
+
+       for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
+               switch (rfpath) {
+               case RF90_PATH_A: {
+                       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                               rtstatus = rtl8812ae_phy_config_rf_with_headerfile(hw,
+                                                                       (enum radio_path)rfpath);
+                       else
+                               rtstatus = rtl8821ae_phy_config_rf_with_headerfile(hw,
+                                                                       (enum radio_path)rfpath);
+                       break;
+                       }
+               case RF90_PATH_B: {
+                       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
+                               rtstatus = rtl8812ae_phy_config_rf_with_headerfile(hw,
+                                                                       (enum radio_path)rfpath);
+                       else
+                               rtstatus = rtl8821ae_phy_config_rf_with_headerfile(hw,
+                                                                       (enum radio_path)rfpath);
+                       break;
+                       }
+               case RF90_PATH_C:
+                       break;
+               case RF90_PATH_D:
+                       break;
+               }
+
+               if (rtstatus != true) {
+                       RT_TRACE(COMP_INIT, DBG_TRACE,
+                                ("Radio[%d] Fail!!", rfpath));
+                       return false;
+               }
+
+       }
+
+       /*put arrays in dm.c*/
+       /*_rtl8821ae_config_rf_txpwr_track_headerfile(hw);*/
+       RT_TRACE(COMP_INIT, DBG_TRACE, ("\n"));
+       return rtstatus;
+}
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/rf.h b/drivers/staging/rtl8821ae/rtl8821ae/rf.h
new file mode 100644 (file)
index 0000000..b665c0f
--- /dev/null
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_RF_H__
+#define __RTL8821AE_RF_H__
+
+#define RF6052_MAX_TX_PWR              0x3F
+#define RF6052_MAX_REG                 0x3F
+
+extern void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
+                                                                                                               u8 bandwidth);
+extern void rtl8821ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+                                                                                                                 u8 *ppowerlevel);
+extern void rtl8821ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+                                                                                                                  u8 *ppowerlevel_ofdm,
+                                                                                                                  u8 *ppowerlevel_bw20,
+                                                                                                                  u8 *ppowerlevel_bw40,
+                                                                                                                  u8 channel);
+extern bool rtl8821ae_phy_rf6052_config(struct ieee80211_hw *hw);
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/sw.c b/drivers/staging/rtl8821ae/rtl8821ae/sw.c
new file mode 100644 (file)
index 0000000..85a3474
--- /dev/null
@@ -0,0 +1,499 @@
+/******************************************************************************
+ *
+ * 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/vmalloc.h>
+#include <linux/module.h>
+
+#include "../wifi.h"
+#include "../core.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "hw.h"
+#include "sw.h"
+#include "trx.h"
+#include "led.h"
+#include "table.h"
+#include "hal_btc.h"
+#include "../btcoexist/rtl_btc.h"
+
+void rtl8821ae_init_aspm_vars(struct ieee80211_hw *hw)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       /*close ASPM for AMD defaultly */
+       rtlpci->const_amdpci_aspm = 0;
+
+       /*
+        * ASPM PS mode.
+        * 0 - Disable ASPM,
+        * 1 - Enable ASPM without Clock Req,
+        * 2 - Enable ASPM with Clock Req,
+        * 3 - Alwyas Enable ASPM with Clock Req,
+        * 4 - Always Enable ASPM without Clock Req.
+        * set defult to RTL8192CE:3 RTL8192E:2
+        * */
+       rtlpci->const_pci_aspm = 3;
+
+       /*Setting for PCI-E device */
+       rtlpci->const_devicepci_aspm_setting = 0x03;
+
+       /*Setting for PCI-E bridge */
+       rtlpci->const_hostpci_aspm_setting = 0x02;
+
+       /*
+        * In Hw/Sw Radio Off situation.
+        * 0 - Default,
+        * 1 - From ASPM setting without low Mac Pwr,
+        * 2 - From ASPM setting with low Mac Pwr,
+        * 3 - Bus D3
+        * set default to RTL8192CE:0 RTL8192SE:2
+        */
+       rtlpci->const_hwsw_rfoff_d3 = 0;
+
+       /*
+        * This setting works for those device with
+        * backdoor ASPM setting such as EPHY setting.
+        * 0 - Not support ASPM,
+        * 1 - Support ASPM,
+        * 2 - According to chipset.
+        */
+       rtlpci->const_support_pciaspm = 1;
+}
+
+/*InitializeVariables8812E*/
+int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
+{
+       int err = 0;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       const struct firmware *firmware;
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       char *fw_name = NULL;
+
+       rtl8821ae_bt_reg_init(hw);
+       rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
+
+       rtlpriv->dm.b_dm_initialgain_enable = 1;
+       rtlpriv->dm.dm_flag = 0;
+       rtlpriv->dm.b_disable_framebursting = 0;;
+       rtlpriv->dm.thermalvalue = 0;
+       rtlpci->transmit_config = CFENDFORM | BIT(15) | BIT(24) | BIT(25);
+
+       mac->ht_enable = true;
+
+       rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
+       /*following 2 is for register 5G band, refer to _rtl_init_mac80211()*/
+       rtlpriv->rtlhal.bandset = BAND_ON_BOTH;
+       rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
+
+       rtlpci->receive_config = (RCR_APPFCS                    |
+                                                         RCR_APP_MIC                   |
+                                                         RCR_APP_ICV                   |
+                                                         RCR_APP_PHYST_RXFF    |
+                                                         RCR_NONQOS_VHT                |
+                                                         RCR_HTC_LOC_CTRL              |
+                                                         RCR_AMF                               |
+                                                         RCR_ACF                               |
+                                                         RCR_ADF                               |       /*This bit controls the PS-Poll packet filter.*/
+                                                         RCR_AICV                              |
+                                                         RCR_ACRC32                    |
+                                                         RCR_AB                                |
+                                                         RCR_AM                                |
+                                                         RCR_APM                               |
+                                                         0);
+
+
+       rtlpci->irq_mask[0] =
+            (u32) (IMR_PSTIMEOUT                       |
+                               IMR_GTINT3                              |
+                               /*IMR_TBDER                             |
+                               IMR_TBDOK                               |
+                               IMR_BCNDMAINT0                  |*/
+                               IMR_HSISR_IND_ON_INT    |
+                               IMR_C2HCMD                              |
+                               IMR_HIGHDOK                             |
+                               IMR_MGNTDOK                             |
+                               IMR_BKDOK                               |
+                               IMR_BEDOK                               |
+                               IMR_VIDOK                               |
+                               IMR_VODOK                               |
+                               IMR_RDU                                 |
+                               IMR_ROK                                 |
+                               0);
+
+       rtlpci->irq_mask[1]     =
+                (u32)( IMR_RXFOVW |
+                               IMR_TXFOVW |
+                               0);
+
+       /* for LPS & IPS */
+       rtlpriv->psc.b_inactiveps = rtlpriv->cfg->mod_params->b_inactiveps;
+       rtlpriv->psc.b_swctrl_lps = rtlpriv->cfg->mod_params->b_swctrl_lps;
+       rtlpriv->psc.b_fwctrl_lps = rtlpriv->cfg->mod_params->b_fwctrl_lps;
+       rtlpriv->psc.b_reg_fwctrl_lps = 3;
+       rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+       /* for ASPM, you can close aspm through
+        * set const_support_pciaspm = 0 */
+       rtl8821ae_init_aspm_vars(hw);
+
+       if (rtlpriv->psc.b_reg_fwctrl_lps == 1)
+               rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
+       else if (rtlpriv->psc.b_reg_fwctrl_lps == 2)
+               rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
+       else if (rtlpriv->psc.b_reg_fwctrl_lps == 3)
+               rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
+
+       /* for firmware buf */
+       rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x8000);
+       if (!rtlpriv->rtlhal.pfirmware) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Can't alloc buffer for fw.\n"));
+               return 1;
+       }
+
+       fw_name = "rtlwifi/rtl8821aefw.bin";
+       err = request_firmware(&firmware, fw_name, rtlpriv->io.dev);
+       if (err) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Failed to request firmware!\n"));
+               return 1;
+       }
+
+       if (firmware->size > 0x8000) {
+               RT_TRACE(COMP_ERR, DBG_EMERG,
+                        ("Firmware is too big!\n"));
+               release_firmware(firmware);
+               return 1;
+       }
+
+       memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+       rtlpriv->rtlhal.fwsize = firmware->size;
+       release_firmware(firmware);
+
+       if (rtlpriv->cfg->ops->get_btc_status()){
+               rtlpriv->btcoexist.btc_ops->btc_init_variables(rtlpriv);
+               rtlpriv->btcoexist.btc_ops->btc_init_hal_vars(rtlpriv);
+       }
+
+       RT_TRACE(COMP_INIT, DBG_LOUD, (" FirmwareDownload OK\n"));
+       return err;
+}
+
+void rtl8821ae_deinit_sw_vars(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       //printk("=========>rtl8821ae_deinit_sw_vars().\n");
+       if (rtlpriv->cfg->ops->get_btc_status()){
+               //printk("=========>rtl8821ae_deinit_sw_vars().get_btc_status\n");
+               rtlpriv->btcoexist.btc_ops->btc_halt_notify();
+       }
+       if (rtlpriv->rtlhal.pfirmware) {
+               //printk("=========>rtl8821ae_deinit_sw_vars().rtlpriv->rtlhal.pfirmware\n");
+               vfree(rtlpriv->rtlhal.pfirmware);
+               rtlpriv->rtlhal.pfirmware = NULL;
+       }
+       //printk("<=========rtl8821ae_deinit_sw_vars().\n");
+}
+
+u32 rtl8812ae_rx_command_packet_handler(
+       struct ieee80211_hw *hw,
+       struct rtl_stats status,
+       struct sk_buff *skb
+       )
+{
+       u32 result = 0;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       switch (status.packet_report_type) {
+               case NORMAL_RX:
+                       result = 0;
+                       break;
+               case C2H_PACKET:
+                       rtl8812ae_c2h_packet_handler(hw, skb->data, (u8) skb->len);
+                       result = 1;
+                       RT_TRACE(COMP_RECV, DBG_LOUD,
+                               ("===>rtl8821ae_rx_command_packet_handler(): (u8) skb->len=%d\n\n", skb->len));
+                       break;
+               default:
+                       RT_TRACE(COMP_RECV, DBG_LOUD,
+                               ("===>rtl8821ae_rx_command_packet_handler(): No this packet type!!\n"));
+                       break;
+       }
+
+       return result;
+}
+
+
+/* get bt coexist status */
+bool rtl8821ae_get_btc_status(void)
+{
+       return true;
+}
+
+struct rtl_hal_ops rtl8821ae_hal_ops = {
+       .init_sw_vars = rtl8821ae_init_sw_vars,
+       .deinit_sw_vars = rtl8821ae_deinit_sw_vars,
+       .read_eeprom_info = rtl8821ae_read_eeprom_info,
+       .interrupt_recognized = rtl8821ae_interrupt_recognized,
+       .hw_init = rtl8821ae_hw_init,
+       .hw_disable = rtl8821ae_card_disable,
+       .hw_suspend = rtl8821ae_suspend,
+       .hw_resume = rtl8821ae_resume,
+       .enable_interrupt = rtl8821ae_enable_interrupt,
+       .disable_interrupt = rtl8821ae_disable_interrupt,
+       .set_network_type = rtl8821ae_set_network_type,
+       .set_chk_bssid = rtl8821ae_set_check_bssid,
+       .set_qos = rtl8821ae_set_qos,
+       .set_bcn_reg = rtl8821ae_set_beacon_related_registers,
+       .set_bcn_intv = rtl8821ae_set_beacon_interval,
+       .update_interrupt_mask = rtl8821ae_update_interrupt_mask,
+       .get_hw_reg = rtl8821ae_get_hw_reg,
+       .set_hw_reg = rtl8821ae_set_hw_reg,
+       .update_rate_tbl = rtl8821ae_update_hal_rate_tbl,
+       .fill_tx_desc = rtl8821ae_tx_fill_desc,
+       .fill_tx_cmddesc = rtl8821ae_tx_fill_cmddesc,
+       .query_rx_desc = rtl8821ae_rx_query_desc,
+       .set_channel_access = rtl8821ae_update_channel_access_setting,
+       .radio_onoff_checking = rtl8821ae_gpio_radio_on_off_checking,
+       .set_bw_mode = rtl8821ae_phy_set_bw_mode,
+       .switch_channel = rtl8821ae_phy_sw_chnl,
+       .dm_watchdog = rtl8821ae_dm_watchdog,
+       .scan_operation_backup = rtl8821ae_phy_scan_operation_backup,
+       .set_rf_power_state = rtl8821ae_phy_set_rf_power_state,
+       .led_control = rtl8821ae_led_control,
+       .set_desc = rtl8821ae_set_desc,
+       .get_desc = rtl8821ae_get_desc,
+       .is_tx_desc_closed = rtl8821ae_is_tx_desc_closed,
+       .tx_polling = rtl8821ae_tx_polling,
+       .enable_hw_sec = rtl8821ae_enable_hw_security_config,
+       .set_key = rtl8821ae_set_key,
+       .init_sw_leds = rtl8821ae_init_sw_leds,
+       .allow_all_destaddr = rtl8821ae_allow_all_destaddr,
+       .get_bbreg = rtl8821ae_phy_query_bb_reg,
+       .set_bbreg = rtl8821ae_phy_set_bb_reg,
+       .get_rfreg = rtl8821ae_phy_query_rf_reg,
+       .set_rfreg = rtl8821ae_phy_set_rf_reg,
+       .c2h_command_handle = rtl_8821ae_c2h_command_handle,
+       .bt_wifi_media_status_notify = rtl_8821ae_bt_wifi_media_status_notify,
+       .bt_turn_off_bt_coexist_before_enter_lps = rtl8821ae_dm_bt_turn_off_bt_coexist_before_enter_lps,
+       .fill_h2c_cmd = rtl8821ae_fill_h2c_cmd,
+       .get_btc_status = rtl8821ae_get_btc_status,
+       .rx_command_packet_handler = rtl8812ae_rx_command_packet_handler,
+};
+
+struct rtl_mod_params rtl8821ae_mod_params = {
+       .sw_crypto = false,
+       .b_inactiveps = false,//true,
+       .b_swctrl_lps = false,
+       .b_fwctrl_lps = false, //true,
+};
+
+struct rtl_hal_cfg rtl8821ae_hal_cfg = {
+       .bar_id = 2,
+       .write_readback = true,
+       .name = "rtl8821ae_pci",
+       .fw_name = "rtlwifi/rtl8821aefw.bin",
+       .ops = &rtl8821ae_hal_ops,
+       .mod_params = &rtl8821ae_mod_params,
+       .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
+       .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
+       .maps[SYS_CLK] = REG_SYS_CLKR,
+       .maps[MAC_RCR_AM] = AM,
+       .maps[MAC_RCR_AB] = AB,
+       .maps[MAC_RCR_ACRC32] = ACRC32,
+       .maps[MAC_RCR_ACF] = ACF,
+       .maps[MAC_RCR_AAP] = AAP,
+       .maps[MAC_HIMR] = REG_HIMR,
+       .maps[MAC_HIMRE] = REG_HIMRE,
+
+
+       .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS,
+
+       .maps[EFUSE_TEST] = REG_EFUSE_TEST,
+       .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
+       .maps[EFUSE_CLK] = 0,
+       .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
+       .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
+       .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
+       .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
+       .maps[EFUSE_ANA8M] = ANA8M,
+       .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
+       .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
+       .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
+       .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
+
+       .maps[RWCAM] = REG_CAMCMD,
+       .maps[WCAMI] = REG_CAMWRITE,
+       .maps[RCAMO] = REG_CAMREAD,
+       .maps[CAMDBG] = REG_CAMDBG,
+       .maps[SECR] = REG_SECCFG,
+       .maps[SEC_CAM_NONE] = CAM_NONE,
+       .maps[SEC_CAM_WEP40] = CAM_WEP40,
+       .maps[SEC_CAM_TKIP] = CAM_TKIP,
+       .maps[SEC_CAM_AES] = CAM_AES,
+       .maps[SEC_CAM_WEP104] = CAM_WEP104,
+
+       .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
+       .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
+       .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
+       .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
+       .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
+       .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
+/*     .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,     */   /*need check*/
+       .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
+       .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
+       .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
+       .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
+       .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
+       .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
+       .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
+/*     .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/
+/*     .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/
+
+       .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
+       .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
+       .maps[RTL_IMR_BcnInt] = IMR_BCNDMAINT0,
+       .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
+       .maps[RTL_IMR_RDU] = IMR_RDU,
+       .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
+       .maps[RTL_IMR_BDOK] = IMR_BCNDOK0,
+       .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
+       .maps[RTL_IMR_TBDER] = IMR_TBDER,
+       .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
+       .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
+       .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
+       .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
+       .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
+       .maps[RTL_IMR_VODOK] = IMR_VODOK,
+       .maps[RTL_IMR_ROK] = IMR_ROK,
+       .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER),
+
+       .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
+       .maps[RTL_RC_CCK_RATE2M] =  DESC_RATE2M,
+       .maps[RTL_RC_CCK_RATE5_5M] =  DESC_RATE5_5M,
+       .maps[RTL_RC_CCK_RATE11M] =  DESC_RATE11M,
+       .maps[RTL_RC_OFDM_RATE6M] =  DESC_RATE6M,
+       .maps[RTL_RC_OFDM_RATE9M] =  DESC_RATE9M,
+       .maps[RTL_RC_OFDM_RATE12M] =  DESC_RATE12M,
+       .maps[RTL_RC_OFDM_RATE18M] =  DESC_RATE18M,
+       .maps[RTL_RC_OFDM_RATE24M] =  DESC_RATE24M,
+       .maps[RTL_RC_OFDM_RATE36M] =  DESC_RATE36M,
+       .maps[RTL_RC_OFDM_RATE48M] =  DESC_RATE48M,
+       .maps[RTL_RC_OFDM_RATE54M] =  DESC_RATE54M,
+
+       .maps[RTL_RC_HT_RATEMCS7] =  DESC_RATEMCS7,
+       .maps[RTL_RC_HT_RATEMCS15] =  DESC_RATEMCS15,
+};
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+static struct pci_device_id rtl8821ae_pci_ids[] = {
+        {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8812, rtl8821ae_hal_cfg)},
+        {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8821, rtl8821ae_hal_cfg)},
+        {},
+};
+#else
+static struct pci_device_id rtl8821ae_pci_ids[] __devinitdata = {
+       {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8812, rtl8821ae_hal_cfg)},
+       {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8821, rtl8821ae_hal_cfg)},
+       {},
+};
+#endif
+
+MODULE_DEVICE_TABLE(pci, rtl8821ae_pci_ids);
+
+MODULE_AUTHOR("Ping Yan<ping_yan@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless");
+MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin");
+
+module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444);
+module_param_named(ips, rtl8821ae_mod_params.b_inactiveps, bool, 0444);
+module_param_named(swlps, rtl8821ae_mod_params.b_swctrl_lps, bool, 0444);
+module_param_named(fwlps, rtl8821ae_mod_params.b_fwctrl_lps, bool, 0444);
+MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
+MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
+MODULE_PARM_DESC(fwlps, "using linked fw control power save (default 1 is open)\n");
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+static const SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+compat_pci_suspend(rtl_pci_suspend)
+compat_pci_resume(rtl_pci_resume)
+#endif
+
+static struct pci_driver rtl8821ae_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = rtl8821ae_pci_ids,
+       .probe = rtl_pci_probe,
+       .remove = rtl_pci_disconnect,
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+       .driver.pm = &rtlwifi_pm_ops,
+#elif defined(CONFIG_PM)
+       .suspend = rtl_pci_suspend_compat,
+       .resume = rtl_pci_resume_compat,
+#endif
+
+};
+
+
+extern int rtl_core_module_init(void);
+extern void rtl_core_module_exit(void);
+
+static int __init rtl8821ae_module_init(void)
+{
+       int ret;
+
+       ret = rtl_core_module_init();
+       if (ret)
+               return ret;
+
+       //printk("==========>rtl8821ae_module_init().\n");
+       ret = pci_register_driver(&rtl8821ae_driver);
+       if (ret)
+               RT_ASSERT(false, (": No device found\n"));
+
+       return ret;
+}
+
+static void __exit rtl8821ae_module_exit(void)
+{
+       pci_unregister_driver(&rtl8821ae_driver);
+       rtl_core_module_exit();
+}
+
+module_init(rtl8821ae_module_init);
+module_exit(rtl8821ae_module_exit);
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/sw.h b/drivers/staging/rtl8821ae/rtl8821ae/sw.h
new file mode 100644 (file)
index 0000000..3d49b2f
--- /dev/null
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_SW_H__
+#define __RTL8821AE_SW_H__
+
+int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw);
+void rtl8821ae_deinit_sw_vars(struct ieee80211_hw *hw);
+void rtl8821ae_init_var_map(struct ieee80211_hw *hw);
+bool rtl8821ae_get_btc_status(void);
+
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/table.c b/drivers/staging/rtl8821ae/rtl8821ae/table.c
new file mode 100644 (file)
index 0000000..a6c4ca4
--- /dev/null
@@ -0,0 +1,4002 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ * Created on  2010/ 5/18,  1:41
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "table.h"
+u32 RTL8812AE_PHY_REG_ARRAY[] = {
+               0x800, 0x8020D010,
+               0x804, 0x080112E0,
+               0x808, 0x0E028233,
+               0x80C, 0x12131113,
+               0x810, 0x20101263,
+               0x814, 0x020C3D10,
+               0x818, 0x03A00385,
+               0x820, 0x00000000,
+               0x824, 0x00030FE0,
+               0x828, 0x00000000,
+               0x82C, 0x002083DD,
+               0x830, 0x2AAA6C86,
+               0x834, 0x0037A706,
+               0x838, 0x06C89B44,
+               0x83C, 0x0000095B,
+               0x840, 0xC0000001,
+               0x844, 0x40003CDE,
+               0x848, 0x6210FF8B,
+               0x84C, 0x6CFDFFB8,
+               0x850, 0x28874706,
+               0x854, 0x0001520C,
+               0x858, 0x8060E000,
+               0x85C, 0x74210168,
+               0x860, 0x6929C321,
+               0x864, 0x79727432,
+               0x868, 0x8CA7A314,
+               0x86C, 0x338C2878,
+               0x870, 0x03333333,
+               0x874, 0x31602C2E,
+               0x878, 0x00003152,
+               0x87C, 0x000FC000,
+               0x8A0, 0x00000013,
+               0x8A4, 0x7F7F7F7F,
+               0x8A8, 0xA202033E,
+               0x8AC, 0x0FF0FA0A,
+               0x8B0, 0x00000600,
+               0x8B4, 0x000FC080,
+               0x8B8, 0x6C0057FF,
+               0x8BC, 0x4CA520A3,
+               0x8C0, 0x27F00020,
+               0x8C4, 0x00000000,
+               0x8C8, 0x00013169,
+               0x8CC, 0x08248492,
+               0x8D0, 0x0000B800,
+               0x8DC, 0x00000000,
+               0x8D4, 0x940008A0,
+               0x8D8, 0x290B5612,
+               0x8F8, 0x400002C0,
+               0x8FC, 0x00000000,
+       0xFF0F07D8, 0xABCD,
+               0x900, 0x00000700,
+       0xFF0F07D0, 0xCDEF,
+               0x900, 0x00000700,
+       0xCDCDCDCD, 0xCDCD,
+               0x900, 0x00000700,
+       0xFF0F07D8, 0xDEAD,
+               0x90C, 0x00000000,
+               0x910, 0x0000FC00,
+               0x914, 0x00000404,
+               0x918, 0x1C1028C0,
+               0x91C, 0x64B11A1C,
+               0x920, 0xE0767233,
+               0x924, 0x055AA500,
+               0x928, 0x00000004,
+               0x92C, 0xFFFE0000,
+               0x930, 0xFFFFFFFE,
+               0x934, 0x001FFFFF,
+               0x960, 0x00000000,
+               0x964, 0x00000000,
+               0x968, 0x00000000,
+               0x96C, 0x00000000,
+               0x970, 0x801FFFFF,
+               0x978, 0x00000000,
+               0x97C, 0x00000000,
+               0x980, 0x00000000,
+               0x984, 0x00000000,
+               0x988, 0x00000000,
+               0x990, 0x27100000,
+               0x994, 0xFFFF0100,
+               0x998, 0xFFFFFF5C,
+               0x99C, 0xFFFFFFFF,
+               0x9A0, 0x000000FF,
+               0x9A4, 0x00080080,
+               0x9A8, 0x00000000,
+               0x9AC, 0x00000000,
+               0x9B0, 0x81081008,
+               0x9B4, 0x00000000,
+               0x9B8, 0x01081008,
+               0x9BC, 0x01081008,
+               0x9D0, 0x00000000,
+               0x9D4, 0x00000000,
+               0x9D8, 0x00000000,
+               0x9DC, 0x00000000,
+               0x9E4, 0x00000002,
+               0x9E8, 0x000002D5,
+               0xA00, 0x00D047C8,
+               0xA04, 0x01FF000C,
+               0xA08, 0x8C838300,
+               0xA0C, 0x2E7F000F,
+               0xA10, 0x9500BB78,
+               0xA14, 0x11144028,
+               0xA18, 0x00881117,
+               0xA1C, 0x89140F00,
+               0xA20, 0x1A1B0000,
+               0xA24, 0x090E1317,
+               0xA28, 0x00000204,
+               0xA2C, 0x00900000,
+               0xA70, 0x101FFF00,
+               0xA74, 0x00000008,
+               0xA78, 0x00000900,
+               0xA7C, 0x225B0606,
+               0xA80, 0x218075B2,
+               0xA84, 0x001F8C80,
+               0xB00, 0x03100000,
+               0xB04, 0x0000B000,
+               0xB08, 0xAE0201EB,
+               0xB0C, 0x01003207,
+               0xB10, 0x00009807,
+               0xB14, 0x01000000,
+               0xB18, 0x00000002,
+               0xB1C, 0x00000002,
+               0xB20, 0x0000001F,
+               0xB24, 0x03020100,
+               0xB28, 0x07060504,
+               0xB2C, 0x0B0A0908,
+               0xB30, 0x0F0E0D0C,
+               0xB34, 0x13121110,
+               0xB38, 0x17161514,
+               0xB3C, 0x0000003A,
+               0xB40, 0x00000000,
+               0xB44, 0x00000000,
+               0xB48, 0x13000032,
+               0xB4C, 0x48080000,
+               0xB50, 0x00000000,
+               0xB54, 0x00000000,
+               0xB58, 0x00000000,
+               0xB5C, 0x00000000,
+               0xC00, 0x00000007,
+               0xC04, 0x00042020,
+               0xC08, 0x80410231,
+               0xC0C, 0x00000000,
+               0xC10, 0x00000100,
+               0xC14, 0x01000000,
+               0xC1C, 0x40000003,
+               0xC20, 0x12121212,
+               0xC24, 0x12121212,
+               0xC28, 0x12121212,
+               0xC2C, 0x12121212,
+               0xC30, 0x12121212,
+               0xC34, 0x12121212,
+               0xC38, 0x12121212,
+               0xC3C, 0x12121212,
+               0xC40, 0x12121212,
+               0xC44, 0x12121212,
+               0xC48, 0x12121212,
+               0xC4C, 0x12121212,
+               0xC50, 0x00000020,
+               0xC54, 0x0008121C,
+               0xC58, 0x30000C1C,
+               0xC5C, 0x00000058,
+               0xC60, 0x34344443,
+               0xC64, 0x07003333,
+               0xC68, 0x59791979,
+               0xC6C, 0x59795979,
+               0xC70, 0x19795979,
+               0xC74, 0x19795979,
+               0xC78, 0x19791979,
+               0xC7C, 0x19791979,
+               0xC80, 0x19791979,
+               0xC84, 0x19791979,
+               0xC94, 0x0100005C,
+               0xC98, 0x00000000,
+               0xC9C, 0x00000000,
+               0xCA0, 0x00000029,
+               0xCA4, 0x08040201,
+               0xCA8, 0x80402010,
+       0xFF0F0740, 0xABCD,
+               0xCB0, 0x77547717,
+       0xFF0F01C0, 0xCDEF,
+               0xCB0, 0x77547717,
+       0xFF0F02C0, 0xCDEF,
+               0xCB0, 0x77547717,
+       0xFF0F07D8, 0xCDEF,
+               0xCB0, 0x54547710,
+       0xFF0F07D0, 0xCDEF,
+               0xCB0, 0x54547710,
+       0xCDCDCDCD, 0xCDCD,
+               0xCB0, 0x77547777,
+       0xFF0F0740, 0xDEAD,
+               0xCB4, 0x00000077,
+               0xCB8, 0x00508242,
+               0xE00, 0x00000007,
+               0xE04, 0x00042020,
+               0xE08, 0x80410231,
+               0xE0C, 0x00000000,
+               0xE10, 0x00000100,
+               0xE14, 0x01000000,
+               0xE1C, 0x40000003,
+               0xE20, 0x12121212,
+               0xE24, 0x12121212,
+               0xE28, 0x12121212,
+               0xE2C, 0x12121212,
+               0xE30, 0x12121212,
+               0xE34, 0x12121212,
+               0xE38, 0x12121212,
+               0xE3C, 0x12121212,
+               0xE40, 0x12121212,
+               0xE44, 0x12121212,
+               0xE48, 0x12121212,
+               0xE4C, 0x12121212,
+               0xE50, 0x00000020,
+               0xE54, 0x0008121C,
+               0xE58, 0x30000C1C,
+               0xE5C, 0x00000058,
+               0xE60, 0x34344443,
+               0xE64, 0x07003333,
+               0xE68, 0x59791979,
+               0xE6C, 0x59795979,
+               0xE70, 0x19795979,
+               0xE74, 0x19795979,
+               0xE78, 0x19791979,
+               0xE7C, 0x19791979,
+               0xE80, 0x19791979,
+               0xE84, 0x19791979,
+               0xE94, 0x0100005C,
+               0xE98, 0x00000000,
+               0xE9C, 0x00000000,
+               0xEA0, 0x00000029,
+               0xEA4, 0x08040201,
+               0xEA8, 0x80402010,
+       0xFF0F0740, 0xABCD,
+               0xEB0, 0x77547717,
+       0xFF0F01C0, 0xCDEF,
+               0xEB0, 0x77547717,
+       0xFF0F02C0, 0xCDEF,
+               0xEB0, 0x77547717,
+       0xFF0F07D8, 0xCDEF,
+               0xEB0, 0x54547710,
+       0xFF0F07D0, 0xCDEF,
+               0xEB0, 0x54547710,
+       0xCDCDCDCD, 0xCDCD,
+               0xEB0, 0x77547777,
+       0xFF0F0740, 0xDEAD,
+               0xEB4, 0x00000077,
+               0xEB8, 0x00508242,
+};
+
+u32 RTL8821AE_PHY_REG_ARRAY[] = {
+       0x800, 0x0020D090,
+       0x804, 0x080112E0,
+       0x808, 0x0E028211,
+       0x80C, 0x92131111,
+       0x810, 0x20101261,
+       0x814, 0x020C3D10,
+       0x818, 0x03A00385,
+       0x820, 0x00000000,
+       0x824, 0x00030FE0,
+       0x828, 0x00000000,
+       0x82C, 0x002081DD,
+       0x830, 0x2AAA8E24,
+       0x834, 0x0037A706,
+       0x838, 0x06489B44,
+       0x83C, 0x0000095B,
+       0x840, 0xC0000001,
+       0x844, 0x40003CDE,
+       0x848, 0x62103F8B,
+       0x84C, 0x6CFDFFB8,
+       0x850, 0x28874706,
+       0x854, 0x0001520C,
+       0x858, 0x8060E000,
+       0x85C, 0x74210168,
+       0x860, 0x6929C321,
+       0x864, 0x79727432,
+       0x868, 0x8CA7A314,
+       0x86C, 0x888C2878,
+       0x870, 0x08888888,
+       0x874, 0x31612C2E,
+       0x878, 0x00000152,
+       0x87C, 0x000FD000,
+       0x8A0, 0x00000013,
+       0x8A4, 0x7F7F7F7F,
+       0x8A8, 0xA2000338,
+       0x8AC, 0x0FF0FA0A,
+       0x8B4, 0x000FC080,
+       0x8B8, 0x6C10D7FF,
+       0x8BC, 0x0CA52090,
+       0x8C0, 0x1BF00020,
+       0x8C4, 0x00000000,
+       0x8C8, 0x00013169,
+       0x8CC, 0x08248492,
+       0x8D4, 0x940008A0,
+       0x8D8, 0x290B5612,
+       0x8F8, 0x400002C0,
+       0x8FC, 0x00000000,
+       0x900, 0x00000700,
+       0x90C, 0x00000000,
+       0x910, 0x0000FC00,
+       0x914, 0x00000404,
+       0x918, 0x1C1028C0,
+       0x91C, 0x64B11A1C,
+       0x920, 0xE0767233,
+       0x924, 0x055AA500,
+       0x928, 0x00000004,
+       0x92C, 0xFFFE0000,
+       0x930, 0xFFFFFFFE,
+       0x934, 0x001FFFFF,
+       0x960, 0x00000000,
+       0x964, 0x00000000,
+       0x968, 0x00000000,
+       0x96C, 0x00000000,
+       0x970, 0x801FFFFF,
+       0x974, 0x000003FF,
+       0x978, 0x00000000,
+       0x97C, 0x00000000,
+       0x980, 0x00000000,
+       0x984, 0x00000000,
+       0x988, 0x00000000,
+       0x990, 0x27100000,
+       0x994, 0xFFFF0100,
+       0x998, 0xFFFFFF5C,
+       0x99C, 0xFFFFFFFF,
+       0x9A0, 0x000000FF,
+       0x9A4, 0x00480080,
+       0x9A8, 0x00000000,
+       0x9AC, 0x00000000,
+       0x9B0, 0x81081008,
+       0x9B4, 0x01081008,
+       0x9B8, 0x01081008,
+       0x9BC, 0x01081008,
+       0x9D0, 0x00000000,
+       0x9D4, 0x00000000,
+       0x9D8, 0x00000000,
+       0x9DC, 0x00000000,
+       0x9E0, 0x00005D00,
+       0x9E4, 0x00000002,
+       0x9E8, 0x00000001,
+       0xA00, 0x00D047C8,
+       0xA04, 0x01FF000C,
+       0xA08, 0x8C8A8300,
+       0xA0C, 0x2E68000F,
+       0xA10, 0x9500BB78,
+       0xA14, 0x11144028,
+       0xA18, 0x00881117,
+       0xA1C, 0x89140F00,
+       0xA20, 0x1A1B0000,
+       0xA24, 0x090E1317,
+       0xA28, 0x00000204,
+       0xA2C, 0x00900000,
+       0xA70, 0x101FFF00,
+       0xA74, 0x00000008,
+       0xA78, 0x00000900,
+       0xA7C, 0x225B0606,
+       0xA80, 0x21805490,
+       0xA84, 0x001F0000,
+       0xB00, 0x03100040,
+       0xB04, 0x0000B000,
+       0xB08, 0xAE0201EB,
+       0xB0C, 0x01003207,
+       0xB10, 0x00009807,
+       0xB14, 0x01000000,
+       0xB18, 0x00000002,
+       0xB1C, 0x00000002,
+       0xB20, 0x0000001F,
+       0xB24, 0x03020100,
+       0xB28, 0x07060504,
+       0xB2C, 0x0B0A0908,
+       0xB30, 0x0F0E0D0C,
+       0xB34, 0x13121110,
+       0xB38, 0x17161514,
+       0xB3C, 0x0000003A,
+       0xB40, 0x00000000,
+       0xB44, 0x00000000,
+       0xB48, 0x13000032,
+       0xB4C, 0x48080000,
+       0xB50, 0x00000000,
+       0xB54, 0x00000000,
+       0xB58, 0x00000000,
+       0xB5C, 0x00000000,
+       0xC00, 0x00000007,
+       0xC04, 0x00042020,
+       0xC08, 0x80410231,
+       0xC0C, 0x00000000,
+       0xC10, 0x00000100,
+       0xC14, 0x01000000,
+       0xC1C, 0x40000003,
+       0xC20, 0x2C2C2C2C,
+       0xC24, 0x30303030,
+       0xC28, 0x30303030,
+       0xC2C, 0x2C2C2C2C,
+       0xC30, 0x2C2C2C2C,
+       0xC34, 0x2C2C2C2C,
+       0xC38, 0x2C2C2C2C,
+       0xC3C, 0x2A2A2A2A,
+       0xC40, 0x2A2A2A2A,
+       0xC44, 0x2A2A2A2A,
+       0xC48, 0x2A2A2A2A,
+       0xC4C, 0x2A2A2A2A,
+       0xC50, 0x00000020,
+       0xC54, 0x001C1208,
+       0xC58, 0x30000C1C,
+       0xC5C, 0x00000058,
+       0xC60, 0x34344443,
+       0xC64, 0x07003333,
+       0xC68, 0x19791979,
+       0xC6C, 0x19791979,
+       0xC70, 0x19791979,
+       0xC74, 0x19791979,
+       0xC78, 0x19791979,
+       0xC7C, 0x19791979,
+       0xC80, 0x19791979,
+       0xC84, 0x19791979,
+       0xC94, 0x0100005C,
+       0xC98, 0x00000000,
+       0xC9C, 0x00000000,
+       0xCA0, 0x00000029,
+       0xCA4, 0x08040201,
+       0xCA8, 0x80402010,
+       0xCB0, 0x77775747,
+       0xCB4, 0x10000077,
+       0xCB8, 0x00508240,
+};
+
+u32 RTL8812AE_PHY_REG_ARRAY_PG[] = {
+       0, 0, 0, 0x00000c20, 0xffffffff, 0x34363840,
+       0, 0, 0, 0x00000c24, 0xffffffff, 0x42424444,
+       0, 0, 0, 0x00000c28, 0xffffffff, 0x30323638,
+       0, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444,
+       0, 0, 0, 0x00000c30, 0xffffffff, 0x28303236,
+       0, 0, 1, 0x00000c34, 0xffffffff, 0x38404242,
+       0, 0, 1, 0x00000c38, 0xffffffff, 0x26283034,
+       0, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444,
+       0, 0, 0, 0x00000c40, 0xffffffff, 0x28303236,
+       0, 0, 0, 0x00000c44, 0xffffffff, 0x42422426,
+       0, 0, 1, 0x00000c48, 0xffffffff, 0x30343840,
+       0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628,
+       0, 1, 0, 0x00000e20, 0xffffffff, 0x34363840,
+       0, 1, 0, 0x00000e24, 0xffffffff, 0x42424444,
+       0, 1, 0, 0x00000e28, 0xffffffff, 0x30323638,
+       0, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444,
+       0, 1, 0, 0x00000e30, 0xffffffff, 0x28303236,
+       0, 1, 1, 0x00000e34, 0xffffffff, 0x38404242,
+       0, 1, 1, 0x00000e38, 0xffffffff, 0x26283034,
+       0, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444,
+       0, 1, 0, 0x00000e40, 0xffffffff, 0x28303236,
+       0, 1, 0, 0x00000e44, 0xffffffff, 0x42422426,
+       0, 1, 1, 0x00000e48, 0xffffffff, 0x30343840,
+       0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628,
+       1, 0, 0, 0x00000c24, 0xffffffff, 0x42424444,
+       1, 0, 0, 0x00000c28, 0xffffffff, 0x30323640,
+       1, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444,
+       1, 0, 0, 0x00000c30, 0xffffffff, 0x28303236,
+       1, 0, 1, 0x00000c34, 0xffffffff, 0x38404242,
+       1, 0, 1, 0x00000c38, 0xffffffff, 0x26283034,
+       1, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444,
+       1, 0, 0, 0x00000c40, 0xffffffff, 0x28303236,
+       1, 0, 0, 0x00000c44, 0xffffffff, 0x42422426,
+       1, 0, 1, 0x00000c48, 0xffffffff, 0x30343840,
+       1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628,
+       1, 1, 0, 0x00000e24, 0xffffffff, 0x42424444,
+       1, 1, 0, 0x00000e28, 0xffffffff, 0x30323640,
+       1, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444,
+       1, 1, 0, 0x00000e30, 0xffffffff, 0x28303236,
+       1, 1, 1, 0x00000e34, 0xffffffff, 0x38404242,
+       1, 1, 1, 0x00000e38, 0xffffffff, 0x26283034,
+       1, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444,
+       1, 1, 0, 0x00000e40, 0xffffffff, 0x28303236,
+       1, 1, 0, 0x00000e44, 0xffffffff, 0x42422426,
+       1, 1, 1, 0x00000e48, 0xffffffff, 0x30343840,
+       1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628
+};
+
+u32 RTL8821AE_PHY_REG_ARRAY_PG[] = {
+       0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638,
+       0, 0, 0, 0x00000c24, 0xffffffff, 0x36363838,
+       0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234,
+       0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363838,
+       0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032,
+       0, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636,
+       0, 0, 0, 0x00000c40, 0xffffffff, 0x24262830,
+       0, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022,
+       1, 0, 0, 0x00000c24, 0xffffffff, 0x34343636,
+       1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032,
+       1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343636,
+       1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830,
+       1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636,
+       1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830,
+       1, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022
+};
+
+/* it seems not used
+u8 *RTL8821AE_TXPWR_LMT_ARRAY[] = {
+       "FCC", "2.4G", "20M", "CCK", "1T", "01", "32",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "01", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "02", "32",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "02", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "02", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "03", "32",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "03", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "03", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "04", "34",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "04", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "04", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "05", "34",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "05", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "05", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "06", "34",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "06", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "06", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "07", "34",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "07", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "07", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "08", "34",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "08", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "08", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "09", "34",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "09", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "09", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "10", "32",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "10", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "10", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "11", "32",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "11", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "11", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "12", "63",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "12", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "12", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "13", "63",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "13", "32",
+       "MKK", "2.4G", "20M", "CCK", "1T", "13", "32",
+       "FCC", "2.4G", "20M", "CCK", "1T", "14", "63",
+       "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63",
+       "MKK", "2.4G", "20M", "CCK", "1T", "14", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "01", "30",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "01", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "02", "30",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "02", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "03", "30",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "03", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "04", "32",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "04", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "05", "32",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "05", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "06", "32",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "06", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "07", "32",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "07", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "08", "32",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "08", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "09", "32",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "09", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "10", "30",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "10", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "11", "30",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "11", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "12", "63",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "12", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "13", "63",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "32",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "13", "32",
+       "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63",
+       "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63",
+       "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63",
+       "FCC", "2.4G", "20M", "HT", "1T", "01", "26",
+       "ETSI", "2.4G", "20M", "HT", "1T", "01", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "01", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "02", "26",
+       "ETSI", "2.4G", "20M", "HT", "1T", "02", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "02", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "03", "26",
+       "ETSI", "2.4G", "20M", "HT", "1T", "03", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "03", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "04", "32",
+       "ETSI", "2.4G", "20M", "HT", "1T", "04", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "04", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "05", "32",
+       "ETSI", "2.4G", "20M", "HT", "1T", "05", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "05", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "06", "32",
+       "ETSI", "2.4G", "20M", "HT", "1T", "06", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "06", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "07", "32",
+       "ETSI", "2.4G", "20M", "HT", "1T", "07", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "07", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "08", "32",
+       "ETSI", "2.4G", "20M", "HT", "1T", "08", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "08", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "09", "32",
+       "ETSI", "2.4G", "20M", "HT", "1T", "09", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "09", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "10", "26",
+       "ETSI", "2.4G", "20M", "HT", "1T", "10", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "10", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "11", "26",
+       "ETSI", "2.4G", "20M", "HT", "1T", "11", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "11", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "12", "63",
+       "ETSI", "2.4G", "20M", "HT", "1T", "12", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "12", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "13", "63",
+       "ETSI", "2.4G", "20M", "HT", "1T", "13", "32",
+       "MKK", "2.4G", "20M", "HT", "1T", "13", "32",
+       "FCC", "2.4G", "20M", "HT", "1T", "14", "63",
+       "ETSI", "2.4G", "20M", "HT", "1T", "14", "63",
+       "MKK", "2.4G", "20M", "HT", "1T", "14", "63",
+       "FCC", "2.4G", "20M", "HT", "2T", "01", "30",
+       "ETSI", "2.4G", "20M", "HT", "2T", "01", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "01", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "02", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "02", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "02", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "03", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "03", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "03", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "04", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "04", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "04", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "05", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "05", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "05", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "06", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "06", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "06", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "07", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "07", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "07", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "08", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "08", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "08", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "09", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "09", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "09", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "10", "32",
+       "ETSI", "2.4G", "20M", "HT", "2T", "10", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "10", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "11", "30",
+       "ETSI", "2.4G", "20M", "HT", "2T", "11", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "11", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "12", "63",
+       "ETSI", "2.4G", "20M", "HT", "2T", "12", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "12", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "13", "63",
+       "ETSI", "2.4G", "20M", "HT", "2T", "13", "32",
+       "MKK", "2.4G", "20M", "HT", "2T", "13", "32",
+       "FCC", "2.4G", "20M", "HT", "2T", "14", "63",
+       "ETSI", "2.4G", "20M", "HT", "2T", "14", "63",
+       "MKK", "2.4G", "20M", "HT", "2T", "14", "63",
+       "FCC", "2.4G", "40M", "HT", "1T", "01", "63",
+       "ETSI", "2.4G", "40M", "HT", "1T", "01", "63",
+       "MKK", "2.4G", "40M", "HT", "1T", "01", "63",
+       "FCC", "2.4G", "40M", "HT", "1T", "02", "63",
+       "ETSI", "2.4G", "40M", "HT", "1T", "02", "63",
+       "MKK", "2.4G", "40M", "HT", "1T", "02", "63",
+       "FCC", "2.4G", "40M", "HT", "1T", "03", "26",
+       "ETSI", "2.4G", "40M", "HT", "1T", "03", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "03", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "04", "26",
+       "ETSI", "2.4G", "40M", "HT", "1T", "04", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "04", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "05", "32",
+       "ETSI", "2.4G", "40M", "HT", "1T", "05", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "05", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "06", "32",
+       "ETSI", "2.4G", "40M", "HT", "1T", "06", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "06", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "07", "32",
+       "ETSI", "2.4G", "40M", "HT", "1T", "07", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "07", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "08", "26",
+       "ETSI", "2.4G", "40M", "HT", "1T", "08", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "08", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "09", "26",
+       "ETSI", "2.4G", "40M", "HT", "1T", "09", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "09", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "10", "26",
+       "ETSI", "2.4G", "40M", "HT", "1T", "10", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "10", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "11", "26",
+       "ETSI", "2.4G", "40M", "HT", "1T", "11", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "11", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "12", "63",
+       "ETSI", "2.4G", "40M", "HT", "1T", "12", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "12", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "13", "63",
+       "ETSI", "2.4G", "40M", "HT", "1T", "13", "32",
+       "MKK", "2.4G", "40M", "HT", "1T", "13", "32",
+       "FCC", "2.4G", "40M", "HT", "1T", "14", "63",
+       "ETSI", "2.4G", "40M", "HT", "1T", "14", "63",
+       "MKK", "2.4G", "40M", "HT", "1T", "14", "63",
+       "FCC", "2.4G", "40M", "HT", "2T", "01", "63",
+       "ETSI", "2.4G", "40M", "HT", "2T", "01", "63",
+       "MKK", "2.4G", "40M", "HT", "2T", "01", "63",
+       "FCC", "2.4G", "40M", "HT", "2T", "02", "63",
+       "ETSI", "2.4G", "40M", "HT", "2T", "02", "63",
+       "MKK", "2.4G", "40M", "HT", "2T", "02", "63",
+       "FCC", "2.4G", "40M", "HT", "2T", "03", "30",
+       "ETSI", "2.4G", "40M", "HT", "2T", "03", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "03", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "04", "32",
+       "ETSI", "2.4G", "40M", "HT", "2T", "04", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "04", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "05", "32",
+       "ETSI", "2.4G", "40M", "HT", "2T", "05", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "05", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "06", "32",
+       "ETSI", "2.4G", "40M", "HT", "2T", "06", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "06", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "07", "32",
+       "ETSI", "2.4G", "40M", "HT", "2T", "07", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "07", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "08", "32",
+       "ETSI", "2.4G", "40M", "HT", "2T", "08", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "08", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "09", "32",
+       "ETSI", "2.4G", "40M", "HT", "2T", "09", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "09", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "10", "32",
+       "ETSI", "2.4G", "40M", "HT", "2T", "10", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "10", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "11", "30",
+       "ETSI", "2.4G", "40M", "HT", "2T", "11", "30",
+       "MKK", "2.4G", "40M", "HT", "2T", "11", "30",
+       "FCC", "2.4G", "40M", "HT", "2T", "12", "63",
+       "ETSI", "2.4G", "40M", "HT", "2T", "12", "32",
+       "MKK", "2.4G", "40M", "HT", "2T", "12", "32",
+       "FCC", "2.4G", "40M", "HT", "2T", "13", "63",
+       "ETSI", "2.4G", "40M", "HT", "2T", "13", "32",
+       "MKK", "2.4G", "40M", "HT", "2T", "13", "32",
+       "FCC", "2.4G", "40M", "HT", "2T", "14", "63",
+       "ETSI", "2.4G", "40M", "HT", "2T", "14", "63",
+       "MKK", "2.4G", "40M", "HT", "2T", "14", "63",
+       "FCC", "5G", "20M", "OFDM", "1T", "36", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "36", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "36", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "40", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "40", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "40", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "44", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "44", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "44", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "48", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "48", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "48", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "52", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "52", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "52", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "56", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "56", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "56", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "60", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "60", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "60", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "64", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "64", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "64", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "100", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "100", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "100", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "114", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "114", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "114", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "108", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "108", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "108", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "112", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "112", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "112", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "116", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "116", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "116", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "120", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "120", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "120", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "124", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "124", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "124", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "128", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "128", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "128", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "132", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "132", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "132", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "136", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "136", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "136", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "140", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "140", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "140", "30",
+       "FCC", "5G", "20M", "OFDM", "1T", "149", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "149", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "149", "63",
+       "FCC", "5G", "20M", "OFDM", "1T", "153", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "153", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "153", "63",
+       "FCC", "5G", "20M", "OFDM", "1T", "157", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "157", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "157", "63",
+       "FCC", "5G", "20M", "OFDM", "1T", "161", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "161", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "161", "63",
+       "FCC", "5G", "20M", "OFDM", "1T", "165", "30",
+       "ETSI", "5G", "20M", "OFDM", "1T", "165", "30",
+       "MKK", "5G", "20M", "OFDM", "1T", "165", "63",
+       "FCC", "5G", "20M", "HT", "1T", "36", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "36", "30",
+       "MKK", "5G", "20M", "HT", "1T", "36", "30",
+       "FCC", "5G", "20M", "HT", "1T", "40", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "40", "30",
+       "MKK", "5G", "20M", "HT", "1T", "40", "30",
+       "FCC", "5G", "20M", "HT", "1T", "44", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "44", "30",
+       "MKK", "5G", "20M", "HT", "1T", "44", "30",
+       "FCC", "5G", "20M", "HT", "1T", "48", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "48", "30",
+       "MKK", "5G", "20M", "HT", "1T", "48", "30",
+       "FCC", "5G", "20M", "HT", "1T", "52", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "52", "30",
+       "MKK", "5G", "20M", "HT", "1T", "52", "30",
+       "FCC", "5G", "20M", "HT", "1T", "56", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "56", "30",
+       "MKK", "5G", "20M", "HT", "1T", "56", "30",
+       "FCC", "5G", "20M", "HT", "1T", "60", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "60", "30",
+       "MKK", "5G", "20M", "HT", "1T", "60", "30",
+       "FCC", "5G", "20M", "HT", "1T", "64", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "64", "30",
+       "MKK", "5G", "20M", "HT", "1T", "64", "30",
+       "FCC", "5G", "20M", "HT", "1T", "100", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "100", "30",
+       "MKK", "5G", "20M", "HT", "1T", "100", "30",
+       "FCC", "5G", "20M", "HT", "1T", "114", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "114", "30",
+       "MKK", "5G", "20M", "HT", "1T", "114", "30",
+       "FCC", "5G", "20M", "HT", "1T", "108", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "108", "30",
+       "MKK", "5G", "20M", "HT", "1T", "108", "30",
+       "FCC", "5G", "20M", "HT", "1T", "112", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "112", "30",
+       "MKK", "5G", "20M", "HT", "1T", "112", "30",
+       "FCC", "5G", "20M", "HT", "1T", "116", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "116", "30",
+       "MKK", "5G", "20M", "HT", "1T", "116", "30",
+       "FCC", "5G", "20M", "HT", "1T", "120", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "120", "30",
+       "MKK", "5G", "20M", "HT", "1T", "120", "30",
+       "FCC", "5G", "20M", "HT", "1T", "124", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "124", "30",
+       "MKK", "5G", "20M", "HT", "1T", "124", "30",
+       "FCC", "5G", "20M", "HT", "1T", "128", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "128", "30",
+       "MKK", "5G", "20M", "HT", "1T", "128", "30",
+       "FCC", "5G", "20M", "HT", "1T", "132", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "132", "30",
+       "MKK", "5G", "20M", "HT", "1T", "132", "30",
+       "FCC", "5G", "20M", "HT", "1T", "136", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "136", "30",
+       "MKK", "5G", "20M", "HT", "1T", "136", "30",
+       "FCC", "5G", "20M", "HT", "1T", "140", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "140", "30",
+       "MKK", "5G", "20M", "HT", "1T", "140", "30",
+       "FCC", "5G", "20M", "HT", "1T", "149", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "149", "30",
+       "MKK", "5G", "20M", "HT", "1T", "149", "63",
+       "FCC", "5G", "20M", "HT", "1T", "153", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "153", "30",
+       "MKK", "5G", "20M", "HT", "1T", "153", "63",
+       "FCC", "5G", "20M", "HT", "1T", "157", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "157", "30",
+       "MKK", "5G", "20M", "HT", "1T", "157", "63",
+       "FCC", "5G", "20M", "HT", "1T", "161", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "161", "30",
+       "MKK", "5G", "20M", "HT", "1T", "161", "63",
+       "FCC", "5G", "20M", "HT", "1T", "165", "30",
+       "ETSI", "5G", "20M", "HT", "1T", "165", "30",
+       "MKK", "5G", "20M", "HT", "1T", "165", "63",
+       "FCC", "5G", "20M", "HT", "2T", "36", "28",
+       "ETSI", "5G", "20M", "HT", "2T", "36", "30",
+       "MKK", "5G", "20M", "HT", "2T", "36", "30",
+       "FCC", "5G", "20M", "HT", "2T", "40", "28",
+       "ETSI", "5G", "20M", "HT", "2T", "40", "30",
+       "MKK", "5G", "20M", "HT", "2T", "40", "30",
+       "FCC", "5G", "20M", "HT", "2T", "44", "28",
+       "ETSI", "5G", "20M", "HT", "2T", "44", "30",
+       "MKK", "5G", "20M", "HT", "2T", "44", "30",
+       "FCC", "5G", "20M", "HT", "2T", "48", "28",
+       "ETSI", "5G", "20M", "HT", "2T", "48", "30",
+       "MKK", "5G", "20M", "HT", "2T", "48", "30",
+       "FCC", "5G", "20M", "HT", "2T", "52", "34",
+       "ETSI", "5G", "20M", "HT", "2T", "52", "30",
+       "MKK", "5G", "20M", "HT", "2T", "52", "30",
+       "FCC", "5G", "20M", "HT", "2T", "56", "32",
+       "ETSI", "5G", "20M", "HT", "2T", "56", "30",
+       "MKK", "5G", "20M", "HT", "2T", "56", "30",
+       "FCC", "5G", "20M", "HT", "2T", "60", "30",
+       "ETSI", "5G", "20M", "HT", "2T", "60", "30",
+       "MKK", "5G", "20M", "HT", "2T", "60", "30",
+       "FCC", "5G", "20M", "HT", "2T", "64", "26",
+       "ETSI", "5G", "20M", "HT", "2T", "64", "30",
+       "MKK", "5G", "20M", "HT", "2T", "64", "30",
+       "FCC", "5G", "20M", "HT", "2T", "100", "28",
+       "ETSI", "5G", "20M", "HT", "2T", "100", "30",
+       "MKK", "5G", "20M", "HT", "2T", "100", "30",
+       "FCC", "5G", "20M", "HT", "2T", "114", "28",
+       "ETSI", "5G", "20M", "HT", "2T", "114", "30",
+       "MKK", "5G", "20M", "HT", "2T", "114", "30",
+       "FCC", "5G", "20M", "HT", "2T", "108", "30",
+       "ETSI", "5G", "20M", "HT", "2T", "108", "30",
+       "MKK", "5G", "20M", "HT", "2T", "108", "30",
+       "FCC", "5G", "20M", "HT", "2T", "112", "32",
+       "ETSI", "5G", "20M", "HT", "2T", "112", "30",
+       "MKK", "5G", "20M", "HT", "2T", "112", "30",
+       "FCC", "5G", "20M", "HT", "2T", "116", "32",
+       "ETSI", "5G", "20M", "HT", "2T", "116", "30",
+       "MKK", "5G", "20M", "HT", "2T", "116", "30",
+       "FCC", "5G", "20M", "HT", "2T", "120", "34",
+       "ETSI", "5G", "20M", "HT", "2T", "120", "30",
+       "MKK", "5G", "20M", "HT", "2T", "120", "30",
+       "FCC", "5G", "20M", "HT", "2T", "124", "32",
+       "ETSI", "5G", "20M", "HT", "2T", "124", "30",
+       "MKK", "5G", "20M", "HT", "2T", "124", "30",
+       "FCC", "5G", "20M", "HT", "2T", "128", "30",
+       "ETSI", "5G", "20M", "HT", "2T", "128", "30",
+       "MKK", "5G", "20M", "HT", "2T", "128", "30",
+       "FCC", "5G", "20M", "HT", "2T", "132", "28",
+       "ETSI", "5G", "20M", "HT", "2T", "132", "30",
+       "MKK", "5G", "20M", "HT", "2T", "132", "30",
+       "FCC", "5G", "20M", "HT", "2T", "136", "28",
+       "ETSI", "5G", "20M", "HT", "2T", "136", "30",
+       "MKK", "5G", "20M", "HT", "2T", "136", "30",
+       "FCC", "5G", "20M", "HT", "2T", "140", "26",
+       "ETSI", "5G", "20M", "HT", "2T", "140", "30",
+       "MKK", "5G", "20M", "HT", "2T", "140", "30",
+       "FCC", "5G", "20M", "HT", "2T", "149", "34",
+       "ETSI", "5G", "20M", "HT", "2T", "149", "30",
+       "MKK", "5G", "20M", "HT", "2T", "149", "63",
+       "FCC", "5G", "20M", "HT", "2T", "153", "34",
+       "ETSI", "5G", "20M", "HT", "2T", "153", "30",
+       "MKK", "5G", "20M", "HT", "2T", "153", "63",
+       "FCC", "5G", "20M", "HT", "2T", "157", "34",
+       "ETSI", "5G", "20M", "HT", "2T", "157", "30",
+       "MKK", "5G", "20M", "HT", "2T", "157", "63",
+       "FCC", "5G", "20M", "HT", "2T", "161", "34",
+       "ETSI", "5G", "20M", "HT", "2T", "161", "30",
+       "MKK", "5G", "20M", "HT", "2T", "161", "63",
+       "FCC", "5G", "20M", "HT", "2T", "165", "34",
+       "ETSI", "5G", "20M", "HT", "2T", "165", "30",
+       "MKK", "5G", "20M", "HT", "2T", "165", "63",
+       "FCC", "5G", "40M", "HT", "1T", "38", "26",
+       "ETSI", "5G", "40M", "HT", "1T", "38", "30",
+       "MKK", "5G", "40M", "HT", "1T", "38", "30",
+       "FCC", "5G", "40M", "HT", "1T", "46", "30",
+       "ETSI", "5G", "40M", "HT", "1T", "46", "30",
+       "MKK", "5G", "40M", "HT", "1T", "46", "30",
+       "FCC", "5G", "40M", "HT", "1T", "54", "30",
+       "ETSI", "5G", "40M", "HT", "1T", "54", "30",
+       "MKK", "5G", "40M", "HT", "1T", "54", "30",
+       "FCC", "5G", "40M", "HT", "1T", "62", "26",
+       "ETSI", "5G", "40M", "HT", "1T", "62", "30",
+       "MKK", "5G", "40M", "HT", "1T", "62", "30",
+       "FCC", "5G", "40M", "HT", "1T", "102", "24",
+       "ETSI", "5G", "40M", "HT", "1T", "102", "30",
+       "MKK", "5G", "40M", "HT", "1T", "102", "30",
+       "FCC", "5G", "40M", "HT", "1T", "110", "30",
+       "ETSI", "5G", "40M", "HT", "1T", "110", "30",
+       "MKK", "5G", "40M", "HT", "1T", "110", "30",
+       "FCC", "5G", "40M", "HT", "1T", "118", "30",
+       "ETSI", "5G", "40M", "HT", "1T", "118", "30",
+       "MKK", "5G", "40M", "HT", "1T", "118", "30",
+       "FCC", "5G", "40M", "HT", "1T", "126", "30",
+       "ETSI", "5G", "40M", "HT", "1T", "126", "30",
+       "MKK", "5G", "40M", "HT", "1T", "126", "30",
+       "FCC", "5G", "40M", "HT", "1T", "134", "30",
+       "ETSI", "5G", "40M", "HT", "1T", "134", "30",
+       "MKK", "5G", "40M", "HT", "1T", "134", "30",
+       "FCC", "5G", "40M", "HT", "1T", "151", "30",
+       "ETSI", "5G", "40M", "HT", "1T", "151", "30",
+       "MKK", "5G", "40M", "HT", "1T", "151", "63",
+       "FCC", "5G", "40M", "HT", "1T", "159", "30",
+       "ETSI", "5G", "40M", "HT", "1T", "159", "30",
+       "MKK", "5G", "40M", "HT", "1T", "159", "63",
+       "FCC", "5G", "40M", "HT", "2T", "38", "28",
+       "ETSI", "5G", "40M", "HT", "2T", "38", "30",
+       "MKK", "5G", "40M", "HT", "2T", "38", "30",
+       "FCC", "5G", "40M", "HT", "2T", "46", "28",
+       "ETSI", "5G", "40M", "HT", "2T", "46", "30",
+       "MKK", "5G", "40M", "HT", "2T", "46", "30",
+       "FCC", "5G", "40M", "HT", "2T", "54", "30",
+       "ETSI", "5G", "40M", "HT", "2T", "54", "30",
+       "MKK", "5G", "40M", "HT", "2T", "54", "30",
+       "FCC", "5G", "40M", "HT", "2T", "62", "30",
+       "ETSI", "5G", "40M", "HT", "2T", "62", "30",
+       "MKK", "5G", "40M", "HT", "2T", "62", "30",
+       "FCC", "5G", "40M", "HT", "2T", "102", "26",
+       "ETSI", "5G", "40M", "HT", "2T", "102", "30",
+       "MKK", "5G", "40M", "HT", "2T", "102", "30",
+       "FCC", "5G", "40M", "HT", "2T", "110", "30",
+       "ETSI", "5G", "40M", "HT", "2T", "110", "30",
+       "MKK", "5G", "40M", "HT", "2T", "110", "30",
+       "FCC", "5G", "40M", "HT", "2T", "118", "34",
+       "ETSI", "5G", "40M", "HT", "2T", "118", "30",
+       "MKK", "5G", "40M", "HT", "2T", "118", "30",
+       "FCC", "5G", "40M", "HT", "2T", "126", "32",
+       "ETSI", "5G", "40M", "HT", "2T", "126", "30",
+       "MKK", "5G", "40M", "HT", "2T", "126", "30",
+       "FCC", "5G", "40M", "HT", "2T", "134", "30",
+       "ETSI", "5G", "40M", "HT", "2T", "134", "30",
+       "MKK", "5G", "40M", "HT", "2T", "134", "30",
+       "FCC", "5G", "40M", "HT", "2T", "151", "34",
+       "ETSI", "5G", "40M", "HT", "2T", "151", "30",
+       "MKK", "5G", "40M", "HT", "2T", "151", "63",
+       "FCC", "5G", "40M", "HT", "2T", "159", "34",
+       "ETSI", "5G", "40M", "HT", "2T", "159", "30",
+       "MKK", "5G", "40M", "HT", "2T", "159", "63",
+       "FCC", "5G", "80M", "VHT", "1T", "42", "22",
+       "ETSI", "5G", "80M", "VHT", "1T", "42", "30",
+       "MKK", "5G", "80M", "VHT", "1T", "42", "30",
+       "FCC", "5G", "80M", "VHT", "1T", "58", "20",
+       "ETSI", "5G", "80M", "VHT", "1T", "58", "30",
+       "MKK", "5G", "80M", "VHT", "1T", "58", "30",
+       "FCC", "5G", "80M", "VHT", "1T", "106", "20",
+       "ETSI", "5G", "80M", "VHT", "1T", "106", "30",
+       "MKK", "5G", "80M", "VHT", "1T", "106", "30",
+       "FCC", "5G", "80M", "VHT", "1T", "122", "28",
+       "ETSI", "5G", "80M", "VHT", "1T", "122", "30",
+       "MKK", "5G", "80M", "VHT", "1T", "122", "30",
+       "FCC", "5G", "80M", "VHT", "1T", "155", "30",
+       "ETSI", "5G", "80M", "VHT", "1T", "155", "30",
+       "MKK", "5G", "80M", "VHT", "1T", "155", "63",
+       "FCC", "5G", "80M", "VHT", "2T", "42", "28",
+       "ETSI", "5G", "80M", "VHT", "2T", "42", "30",
+       "MKK", "5G", "80M", "VHT", "2T", "42", "30",
+       "FCC", "5G", "80M", "VHT", "2T", "58", "26",
+       "ETSI", "5G", "80M", "VHT", "2T", "58", "30",
+       "MKK", "5G", "80M", "VHT", "2T", "58", "30",
+       "FCC", "5G", "80M", "VHT", "2T", "106", "28",
+       "ETSI", "5G", "80M", "VHT", "2T", "106", "30",
+       "MKK", "5G", "80M", "VHT", "2T", "106", "30",
+       "FCC", "5G", "80M", "VHT", "2T", "122", "32",
+       "ETSI", "5G", "80M", "VHT", "2T", "122", "30",
+       "MKK", "5G", "80M", "VHT", "2T", "122", "30",
+       "FCC", "5G", "80M", "VHT", "2T", "155", "34",
+       "ETSI", "5G", "80M", "VHT", "2T", "155", "30",
+       "MKK", "5G", "80M", "VHT", "2T", "155", "63"
+};*/
+
+u32 RTL8812AE_RADIOA_ARRAY[] = {
+               0x000, 0x00010000,
+               0x018, 0x0001712A,
+               0x056, 0x00051CF2,
+               0x066, 0x00040000,
+               0x01E, 0x00080000,
+               0x089, 0x00000080,
+       0xFF0F0740, 0xABCD,
+               0x086, 0x00014B38,
+       0xFF0F02C0, 0xCDEF,
+               0x086, 0x00014B38,
+       0xFF0F01C0, 0xCDEF,
+               0x086, 0x00014B38,
+       0xFF0F07D8, 0xCDEF,
+               0x086, 0x00014B3A,
+       0xFF0F07D0, 0xCDEF,
+               0x086, 0x00014B3A,
+       0xCDCDCDCD, 0xCDCD,
+               0x086, 0x00014B38,
+       0xFF0F0740, 0xDEAD,
+               0x0B1, 0x0001FC1A,
+               0x0B3, 0x000F0810,
+               0x0B4, 0x0001A78D,
+               0x0BA, 0x00086180,
+               0x018, 0x00000006,
+               0x0EF, 0x00002000,
+       0xFF0F07D8, 0xABCD,
+               0x03B, 0x0003F218,
+               0x03B, 0x00030A58,
+               0x03B, 0x0002FA58,
+               0x03B, 0x00022590,
+               0x03B, 0x0001FA50,
+               0x03B, 0x00010248,
+               0x03B, 0x00008240,
+       0xFF0F07D0, 0xCDEF,
+               0x03B, 0x0003F218,
+               0x03B, 0x00030A58,
+               0x03B, 0x0002FA58,
+               0x03B, 0x00022590,
+               0x03B, 0x0001FA50,
+               0x03B, 0x00010248,
+               0x03B, 0x00008240,
+       0xCDCDCDCD, 0xCDCD,
+               0x03B, 0x00038A58,
+               0x03B, 0x00037A58,
+               0x03B, 0x0002A590,
+               0x03B, 0x00027A50,
+               0x03B, 0x00018248,
+               0x03B, 0x00010240,
+               0x03B, 0x00008240,
+       0xFF0F07D8, 0xDEAD,
+               0x0EF, 0x00000100,
+       0xFF0F07D8, 0xABCD,
+               0x034, 0x0000A4EE,
+               0x034, 0x00009076,
+               0x034, 0x00008073,
+               0x034, 0x00007070,
+               0x034, 0x0000606D,
+               0x034, 0x0000506A,
+               0x034, 0x00004049,
+               0x034, 0x00003046,
+               0x034, 0x00002028,
+               0x034, 0x00001025,
+               0x034, 0x00000022,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0000ADF4,
+               0x034, 0x00009DF1,
+               0x034, 0x00008DEE,
+               0x034, 0x00007DEB,
+               0x034, 0x00006DE8,
+               0x034, 0x00005CEC,
+               0x034, 0x00004CE9,
+               0x034, 0x000034EA,
+               0x034, 0x000024E7,
+               0x034, 0x0000146B,
+               0x034, 0x0000006D,
+       0xFF0F07D8, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x0EF, 0x000020A2,
+               0x0DF, 0x00000080,
+               0x035, 0x00000192,
+               0x035, 0x00008192,
+               0x035, 0x00010192,
+               0x036, 0x00000024,
+               0x036, 0x00008024,
+               0x036, 0x00010024,
+               0x036, 0x00018024,
+               0x0EF, 0x00000000,
+               0x051, 0x00000C21,
+               0x052, 0x000006D9,
+               0x053, 0x000FC649,
+               0x054, 0x0000017E,
+               0x0EF, 0x00000002,
+               0x008, 0x00008400,
+               0x018, 0x0001712A,
+               0x0EF, 0x00001000,
+               0x03A, 0x00000080,
+               0x03B, 0x0003A02C,
+               0x03C, 0x00004000,
+               0x03A, 0x00000400,
+               0x03B, 0x0003202C,
+               0x03C, 0x00010000,
+               0x03A, 0x000000A0,
+               0x03B, 0x0002B064,
+               0x03C, 0x00004000,
+               0x03A, 0x000000D8,
+               0x03B, 0x00023070,
+               0x03C, 0x00004000,
+               0x03A, 0x00000468,
+               0x03B, 0x0001B870,
+               0x03C, 0x00010000,
+               0x03A, 0x00000098,
+               0x03B, 0x00012085,
+               0x03C, 0x000E4000,
+               0x03A, 0x00000418,
+               0x03B, 0x0000A080,
+               0x03C, 0x000F0000,
+               0x03A, 0x00000418,
+               0x03B, 0x00002080,
+               0x03C, 0x00010000,
+               0x03A, 0x00000080,
+               0x03B, 0x0007A02C,
+               0x03C, 0x00004000,
+               0x03A, 0x00000400,
+               0x03B, 0x0007202C,
+               0x03C, 0x00010000,
+               0x03A, 0x000000A0,
+               0x03B, 0x0006B064,
+               0x03C, 0x00004000,
+               0x03A, 0x000000D8,
+               0x03B, 0x00023070,
+               0x03C, 0x00004000,
+               0x03A, 0x00000468,
+               0x03B, 0x0005B870,
+               0x03C, 0x00010000,
+               0x03A, 0x00000098,
+               0x03B, 0x00052085,
+               0x03C, 0x000E4000,
+               0x03A, 0x00000418,
+               0x03B, 0x0004A080,
+               0x03C, 0x000F0000,
+               0x03A, 0x00000418,
+               0x03B, 0x00042080,
+               0x03C, 0x00010000,
+               0x03A, 0x00000080,
+               0x03B, 0x000BA02C,
+               0x03C, 0x00004000,
+               0x03A, 0x00000400,
+               0x03B, 0x000B202C,
+               0x03C, 0x00010000,
+               0x03A, 0x000000A0,
+               0x03B, 0x000AB064,
+               0x03C, 0x00004000,
+               0x03A, 0x000000D8,
+               0x03B, 0x000A3070,
+               0x03C, 0x00004000,
+               0x03A, 0x00000468,
+               0x03B, 0x0009B870,
+               0x03C, 0x00010000,
+               0x03A, 0x00000098,
+               0x03B, 0x00092085,
+               0x03C, 0x000E4000,
+               0x03A, 0x00000418,
+               0x03B, 0x0008A080,
+               0x03C, 0x000F0000,
+               0x03A, 0x00000418,
+               0x03B, 0x00082080,
+               0x03C, 0x00010000,
+               0x0EF, 0x00001100,
+       0xFF0F0740, 0xABCD,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xFF0F01C0, 0xCDEF,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xFF0F07D8, 0xCDEF,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xFF0F07D0, 0xCDEF,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0004ADF5,
+               0x034, 0x00049DF2,
+               0x034, 0x00048DEF,
+               0x034, 0x00047DEC,
+               0x034, 0x00046DE9,
+               0x034, 0x00045DC9,
+               0x034, 0x00044CE8,
+               0x034, 0x000438CA,
+               0x034, 0x00042889,
+               0x034, 0x0004184A,
+               0x034, 0x0004044A,
+       0xFF0F0740, 0xDEAD,
+       0xFF0F0740, 0xABCD,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xFF0F01C0, 0xCDEF,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xFF0F07D8, 0xCDEF,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xFF0F07D0, 0xCDEF,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0002ADF5,
+               0x034, 0x00029DF2,
+               0x034, 0x00028DEF,
+               0x034, 0x00027DEC,
+               0x034, 0x00026DE9,
+               0x034, 0x00025DC9,
+               0x034, 0x00024CE8,
+               0x034, 0x000238CA,
+               0x034, 0x00022889,
+               0x034, 0x0002184A,
+               0x034, 0x0002044A,
+       0xFF0F0740, 0xDEAD,
+       0xFF0F0740, 0xABCD,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xFF0F01C0, 0xCDEF,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xFF0F07D8, 0xCDEF,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xFF0F07D0, 0xCDEF,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0000AFF7,
+               0x034, 0x00009DF7,
+               0x034, 0x00008DF4,
+               0x034, 0x00007DF1,
+               0x034, 0x00006DEE,
+               0x034, 0x00005DCD,
+               0x034, 0x00004CEB,
+               0x034, 0x000038CC,
+               0x034, 0x0000288B,
+               0x034, 0x0000184C,
+               0x034, 0x0000044C,
+       0xFF0F0740, 0xDEAD,
+               0x0EF, 0x00000000,
+       0xFF0F0740, 0xABCD,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001D4,
+               0x035, 0x000081D4,
+               0x035, 0x000101D4,
+               0x035, 0x000201B4,
+               0x035, 0x000281B4,
+               0x035, 0x000301B4,
+               0x035, 0x000401B4,
+               0x035, 0x000481B4,
+               0x035, 0x000501B4,
+       0xFF0F02C0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001D4,
+               0x035, 0x000081D4,
+               0x035, 0x000101D4,
+               0x035, 0x000201B4,
+               0x035, 0x000281B4,
+               0x035, 0x000301B4,
+               0x035, 0x000401B4,
+               0x035, 0x000481B4,
+               0x035, 0x000501B4,
+       0xFF0F01C0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001D4,
+               0x035, 0x000081D4,
+               0x035, 0x000101D4,
+               0x035, 0x000201B4,
+               0x035, 0x000281B4,
+               0x035, 0x000301B4,
+               0x035, 0x000401B4,
+               0x035, 0x000481B4,
+               0x035, 0x000501B4,
+       0xFF0F07D8, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001D4,
+               0x035, 0x000081D4,
+               0x035, 0x000101D4,
+               0x035, 0x000201B4,
+               0x035, 0x000281B4,
+               0x035, 0x000301B4,
+               0x035, 0x000401B4,
+               0x035, 0x000481B4,
+               0x035, 0x000501B4,
+       0xFF0F07D0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001D4,
+               0x035, 0x000081D4,
+               0x035, 0x000101D4,
+               0x035, 0x000201B4,
+               0x035, 0x000281B4,
+               0x035, 0x000301B4,
+               0x035, 0x000401B4,
+               0x035, 0x000481B4,
+               0x035, 0x000501B4,
+       0xCDCDCDCD, 0xCDCD,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x00000188,
+               0x035, 0x00008147,
+               0x035, 0x00010147,
+               0x035, 0x000201D7,
+               0x035, 0x000281D7,
+               0x035, 0x000301D7,
+               0x035, 0x000401D8,
+               0x035, 0x000481D8,
+               0x035, 0x000501D8,
+       0xFF0F0740, 0xDEAD,
+               0x0EF, 0x00000000,
+       0xFF0F0740, 0xABCD,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00004BFB,
+               0x036, 0x0000CBFB,
+               0x036, 0x00014BFB,
+               0x036, 0x0001CBFB,
+               0x036, 0x00024F4B,
+               0x036, 0x0002CF4B,
+               0x036, 0x00034F4B,
+               0x036, 0x0003CF4B,
+               0x036, 0x00044F4B,
+               0x036, 0x0004CF4B,
+               0x036, 0x00054F4B,
+               0x036, 0x0005CF4B,
+       0xFF0F02C0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00004BFB,
+               0x036, 0x0000CBFB,
+               0x036, 0x00014BFB,
+               0x036, 0x0001CBFB,
+               0x036, 0x00024F4B,
+               0x036, 0x0002CF4B,
+               0x036, 0x00034F4B,
+               0x036, 0x0003CF4B,
+               0x036, 0x00044F4B,
+               0x036, 0x0004CF4B,
+               0x036, 0x00054F4B,
+               0x036, 0x0005CF4B,
+       0xFF0F01C0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00004BFB,
+               0x036, 0x0000CBFB,
+               0x036, 0x00014BFB,
+               0x036, 0x0001CBFB,
+               0x036, 0x00024F4B,
+               0x036, 0x0002CF4B,
+               0x036, 0x00034F4B,
+               0x036, 0x0003CF4B,
+               0x036, 0x00044F4B,
+               0x036, 0x0004CF4B,
+               0x036, 0x00054F4B,
+               0x036, 0x0005CF4B,
+       0xFF0F07D8, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00004BFB,
+               0x036, 0x0000CBFB,
+               0x036, 0x00014BFB,
+               0x036, 0x0001CBFB,
+               0x036, 0x00024F4B,
+               0x036, 0x0002CF4B,
+               0x036, 0x00034F4B,
+               0x036, 0x0003CF4B,
+               0x036, 0x00044F4B,
+               0x036, 0x0004CF4B,
+               0x036, 0x00054F4B,
+               0x036, 0x0005CF4B,
+       0xFF0F07D0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00004BFB,
+               0x036, 0x0000CBFB,
+               0x036, 0x00014BFB,
+               0x036, 0x0001CBFB,
+               0x036, 0x00024F4B,
+               0x036, 0x0002CF4B,
+               0x036, 0x00034F4B,
+               0x036, 0x0003CF4B,
+               0x036, 0x00044F4B,
+               0x036, 0x0004CF4B,
+               0x036, 0x00054F4B,
+               0x036, 0x0005CF4B,
+       0xCDCDCDCD, 0xCDCD,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00084EB4,
+               0x036, 0x0008CC35,
+               0x036, 0x00094C35,
+               0x036, 0x0009CC35,
+               0x036, 0x000A4935,
+               0x036, 0x000ACC35,
+               0x036, 0x000B4C35,
+               0x036, 0x000BCC35,
+               0x036, 0x000C4EB4,
+               0x036, 0x000CCEB5,
+               0x036, 0x000D4EB5,
+               0x036, 0x000DCEB5,
+       0xFF0F0740, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x0EF, 0x00000008,
+       0xFF0F0740, 0xABCD,
+               0x03C, 0x000002CC,
+               0x03C, 0x00000522,
+               0x03C, 0x00000902,
+       0xFF0F02C0, 0xCDEF,
+               0x03C, 0x000002CC,
+               0x03C, 0x00000522,
+               0x03C, 0x00000902,
+       0xFF0F01C0, 0xCDEF,
+               0x03C, 0x000002CC,
+               0x03C, 0x00000522,
+               0x03C, 0x00000902,
+       0xFF0F07D8, 0xCDEF,
+               0x03C, 0x000002CC,
+               0x03C, 0x00000522,
+               0x03C, 0x00000902,
+       0xFF0F07D0, 0xCDEF,
+               0x03C, 0x000002CC,
+               0x03C, 0x00000522,
+               0x03C, 0x00000902,
+       0xCDCDCDCD, 0xCDCD,
+               0x03C, 0x000002A8,
+               0x03C, 0x000005A2,
+               0x03C, 0x00000880,
+       0xFF0F0740, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000002,
+               0x0DF, 0x00000080,
+               0x01F, 0x00040064,
+       0xFF0F0740, 0xABCD,
+               0x061, 0x000FDD43,
+               0x062, 0x00038F4B,
+               0x063, 0x00032117,
+               0x064, 0x000194AC,
+               0x065, 0x000931D1,
+       0xFF0F02C0, 0xCDEF,
+               0x061, 0x000FDD43,
+               0x062, 0x00038F4B,
+               0x063, 0x00032117,
+               0x064, 0x000194AC,
+               0x065, 0x000931D1,
+       0xFF0F01C0, 0xCDEF,
+               0x061, 0x000FDD43,
+               0x062, 0x00038F4B,
+               0x063, 0x00032117,
+               0x064, 0x000194AC,
+               0x065, 0x000931D1,
+       0xFF0F07D8, 0xCDEF,
+               0x061, 0x000FDD43,
+               0x062, 0x00038F4B,
+               0x063, 0x00032117,
+               0x064, 0x000194AC,
+               0x065, 0x000931D1,
+       0xFF0F07D0, 0xCDEF,
+               0x061, 0x000FDD43,
+               0x062, 0x00038F4B,
+               0x063, 0x00032117,
+               0x064, 0x000194AC,
+               0x065, 0x000931D1,
+       0xCDCDCDCD, 0xCDCD,
+               0x061, 0x000E5D53,
+               0x062, 0x00038FCD,
+               0x063, 0x000314EB,
+               0x064, 0x000196AC,
+               0x065, 0x000911D7,
+       0xFF0F0740, 0xDEAD,
+               0x008, 0x00008400,
+               0x01C, 0x000739D2,
+               0x0B4, 0x0001E78D,
+               0x018, 0x0001F12A,
+               0x0FE, 0x00000000,
+               0x0FE, 0x00000000,
+               0x0FE, 0x00000000,
+               0x0FE, 0x00000000,
+               0x0B4, 0x0001A78D,
+               0x018, 0x0001712A,
+};
+
+u32 RTL8812AE_RADIOB_ARRAY[] = {
+               0x056, 0x00051CF2,
+               0x066, 0x00040000,
+               0x089, 0x00000080,
+       0xFF0F0740, 0xABCD,
+               0x086, 0x00014B38,
+       0xFF0F01C0, 0xCDEF,
+               0x086, 0x00014B38,
+       0xFF0F02C0, 0xCDEF,
+               0x086, 0x00014B38,
+       0xFF0F07D8, 0xCDEF,
+               0x086, 0x00014B3A,
+       0xFF0F07D0, 0xCDEF,
+               0x086, 0x00014B3A,
+       0xCDCDCDCD, 0xCDCD,
+               0x086, 0x00014B38,
+       0xFF0F0740, 0xDEAD,
+               0x018, 0x00000006,
+               0x0EF, 0x00002000,
+       0xFF0F07D8, 0xABCD,
+               0x03B, 0x0003F218,
+               0x03B, 0x00030A58,
+               0x03B, 0x0002FA58,
+               0x03B, 0x00022590,
+               0x03B, 0x0001FA50,
+               0x03B, 0x00010248,
+               0x03B, 0x00008240,
+       0xFF0F07D0, 0xCDEF,
+               0x03B, 0x0003F218,
+               0x03B, 0x00030A58,
+               0x03B, 0x0002FA58,
+               0x03B, 0x00022590,
+               0x03B, 0x0001FA50,
+               0x03B, 0x00010248,
+               0x03B, 0x00008240,
+       0xCDCDCDCD, 0xCDCD,
+               0x03B, 0x00038A58,
+               0x03B, 0x00037A58,
+               0x03B, 0x0002A590,
+               0x03B, 0x00027A50,
+               0x03B, 0x00018248,
+               0x03B, 0x00010240,
+               0x03B, 0x00008240,
+       0xFF0F07D8, 0xDEAD,
+               0x0EF, 0x00000100,
+       0xFF0F07D8, 0xABCD,
+               0x034, 0x0000A4EE,
+               0x034, 0x00009076,
+               0x034, 0x00008073,
+               0x034, 0x00007070,
+               0x034, 0x0000606D,
+               0x034, 0x0000506A,
+               0x034, 0x00004049,
+               0x034, 0x00003046,
+               0x034, 0x00002028,
+               0x034, 0x00001025,
+               0x034, 0x00000022,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0000ADF4,
+               0x034, 0x00009DF1,
+               0x034, 0x00008DEE,
+               0x034, 0x00007DEB,
+               0x034, 0x00006DE8,
+               0x034, 0x00005CEC,
+               0x034, 0x00004CE9,
+               0x034, 0x000034EA,
+               0x034, 0x000024E7,
+               0x034, 0x0000146B,
+               0x034, 0x0000006D,
+       0xFF0F07D8, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x0EF, 0x000020A2,
+               0x0DF, 0x00000080,
+               0x035, 0x00000192,
+               0x035, 0x00008192,
+               0x035, 0x00010192,
+               0x036, 0x00000024,
+               0x036, 0x00008024,
+               0x036, 0x00010024,
+               0x036, 0x00018024,
+               0x0EF, 0x00000000,
+               0x051, 0x00000C21,
+               0x052, 0x000006D9,
+               0x053, 0x000FC649,
+               0x054, 0x0000017E,
+               0x0EF, 0x00000002,
+               0x008, 0x00008400,
+               0x018, 0x0001712A,
+               0x0EF, 0x00001000,
+               0x03A, 0x00000080,
+               0x03B, 0x0003A02C,
+               0x03C, 0x00004000,
+               0x03A, 0x00000400,
+               0x03B, 0x0003202C,
+               0x03C, 0x00010000,
+               0x03A, 0x000000A0,
+               0x03B, 0x0002B064,
+               0x03C, 0x00004000,
+               0x03A, 0x000000D8,
+               0x03B, 0x00023070,
+               0x03C, 0x00004000,
+               0x03A, 0x00000468,
+               0x03B, 0x0001B870,
+               0x03C, 0x00010000,
+               0x03A, 0x00000098,
+               0x03B, 0x00012085,
+               0x03C, 0x000E4000,
+               0x03A, 0x00000418,
+               0x03B, 0x0000A080,
+               0x03C, 0x000F0000,
+               0x03A, 0x00000418,
+               0x03B, 0x00002080,
+               0x03C, 0x00010000,
+               0x03A, 0x00000080,
+               0x03B, 0x0007A02C,
+               0x03C, 0x00004000,
+               0x03A, 0x00000400,
+               0x03B, 0x0007202C,
+               0x03C, 0x00010000,
+               0x03A, 0x000000A0,
+               0x03B, 0x0006B064,
+               0x03C, 0x00004000,
+               0x03A, 0x000000D8,
+               0x03B, 0x00063070,
+               0x03C, 0x00004000,
+               0x03A, 0x00000468,
+               0x03B, 0x0005B870,
+               0x03C, 0x00010000,
+               0x03A, 0x00000098,
+               0x03B, 0x00052085,
+               0x03C, 0x000E4000,
+               0x03A, 0x00000418,
+               0x03B, 0x0004A080,
+               0x03C, 0x000F0000,
+               0x03A, 0x00000418,
+               0x03B, 0x00042080,
+               0x03C, 0x00010000,
+               0x03A, 0x00000080,
+               0x03B, 0x000BA02C,
+               0x03C, 0x00004000,
+               0x03A, 0x00000400,
+               0x03B, 0x000B202C,
+               0x03C, 0x00010000,
+               0x03A, 0x000000A0,
+               0x03B, 0x000AB064,
+               0x03C, 0x00004000,
+               0x03A, 0x000000D8,
+               0x03B, 0x000A3070,
+               0x03C, 0x00004000,
+               0x03A, 0x00000468,
+               0x03B, 0x0009B870,
+               0x03C, 0x00010000,
+               0x03A, 0x00000098,
+               0x03B, 0x00092085,
+               0x03C, 0x000E4000,
+               0x03A, 0x00000418,
+               0x03B, 0x0008A080,
+               0x03C, 0x000F0000,
+               0x03A, 0x00000418,
+               0x03B, 0x00082080,
+               0x03C, 0x00010000,
+               0x0EF, 0x00001100,
+       0xFF0F0740, 0xABCD,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xFF0F01C0, 0xCDEF,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xFF0F07D8, 0xCDEF,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xFF0F07D0, 0xCDEF,
+               0x034, 0x0004A0B2,
+               0x034, 0x000490AF,
+               0x034, 0x00048070,
+               0x034, 0x0004706D,
+               0x034, 0x00046050,
+               0x034, 0x0004504D,
+               0x034, 0x0004404A,
+               0x034, 0x00043047,
+               0x034, 0x0004200A,
+               0x034, 0x00041007,
+               0x034, 0x00040004,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0004ADF5,
+               0x034, 0x00049DF2,
+               0x034, 0x00048DEF,
+               0x034, 0x00047DEC,
+               0x034, 0x00046DE9,
+               0x034, 0x00045DC9,
+               0x034, 0x00044CE8,
+               0x034, 0x000438CA,
+               0x034, 0x00042889,
+               0x034, 0x0004184A,
+               0x034, 0x0004044A,
+       0xFF0F0740, 0xDEAD,
+       0xFF0F0740, 0xABCD,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xFF0F01C0, 0xCDEF,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xFF0F07D8, 0xCDEF,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xFF0F07D0, 0xCDEF,
+               0x034, 0x0002A0B2,
+               0x034, 0x000290AF,
+               0x034, 0x00028070,
+               0x034, 0x0002706D,
+               0x034, 0x00026050,
+               0x034, 0x0002504D,
+               0x034, 0x0002404A,
+               0x034, 0x00023047,
+               0x034, 0x0002200A,
+               0x034, 0x00021007,
+               0x034, 0x00020004,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0002ADF5,
+               0x034, 0x00029DF2,
+               0x034, 0x00028DEF,
+               0x034, 0x00027DEC,
+               0x034, 0x00026DE9,
+               0x034, 0x00025DC9,
+               0x034, 0x00024CE8,
+               0x034, 0x000238CA,
+               0x034, 0x00022889,
+               0x034, 0x0002184A,
+               0x034, 0x0002044A,
+       0xFF0F0740, 0xDEAD,
+       0xFF0F0740, 0xABCD,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xFF0F01C0, 0xCDEF,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xFF0F07D8, 0xCDEF,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xFF0F07D0, 0xCDEF,
+               0x034, 0x0000A0B2,
+               0x034, 0x000090AF,
+               0x034, 0x00008070,
+               0x034, 0x0000706D,
+               0x034, 0x00006050,
+               0x034, 0x0000504D,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x0000200A,
+               0x034, 0x00001007,
+               0x034, 0x00000004,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0000AFF7,
+               0x034, 0x00009DF7,
+               0x034, 0x00008DF4,
+               0x034, 0x00007DF1,
+               0x034, 0x00006DEE,
+               0x034, 0x00005DCD,
+               0x034, 0x00004CEB,
+               0x034, 0x000038CC,
+               0x034, 0x0000288B,
+               0x034, 0x0000184C,
+               0x034, 0x0000044C,
+       0xFF0F0740, 0xDEAD,
+               0x0EF, 0x00000000,
+       0xFF0F0740, 0xABCD,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001C5,
+               0x035, 0x000081C5,
+               0x035, 0x000101C5,
+               0x035, 0x00020174,
+               0x035, 0x00028174,
+               0x035, 0x00030174,
+               0x035, 0x00040185,
+               0x035, 0x00048185,
+               0x035, 0x00050185,
+               0x0EF, 0x00000000,
+       0xFF0F01C0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001C5,
+               0x035, 0x000081C5,
+               0x035, 0x000101C5,
+               0x035, 0x00020174,
+               0x035, 0x00028174,
+               0x035, 0x00030174,
+               0x035, 0x00040185,
+               0x035, 0x00048185,
+               0x035, 0x00050185,
+               0x0EF, 0x00000000,
+       0xFF0F02C0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001C5,
+               0x035, 0x000081C5,
+               0x035, 0x000101C5,
+               0x035, 0x00020174,
+               0x035, 0x00028174,
+               0x035, 0x00030174,
+               0x035, 0x00040185,
+               0x035, 0x00048185,
+               0x035, 0x00050185,
+               0x0EF, 0x00000000,
+       0xFF0F07D8, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001C5,
+               0x035, 0x000081C5,
+               0x035, 0x000101C5,
+               0x035, 0x00020174,
+               0x035, 0x00028174,
+               0x035, 0x00030174,
+               0x035, 0x00040185,
+               0x035, 0x00048185,
+               0x035, 0x00050185,
+               0x0EF, 0x00000000,
+       0xFF0F07D0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x000001C5,
+               0x035, 0x000081C5,
+               0x035, 0x000101C5,
+               0x035, 0x00020174,
+               0x035, 0x00028174,
+               0x035, 0x00030174,
+               0x035, 0x00040185,
+               0x035, 0x00048185,
+               0x035, 0x00050185,
+               0x0EF, 0x00000000,
+       0xCDCDCDCD, 0xCDCD,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+               0x035, 0x00000186,
+               0x035, 0x00008186,
+               0x035, 0x00010185,
+               0x035, 0x000201D5,
+               0x035, 0x000281D5,
+               0x035, 0x000301D5,
+               0x035, 0x000401D5,
+               0x035, 0x000481D5,
+               0x035, 0x000501D5,
+               0x0EF, 0x00000000,
+       0xFF0F0740, 0xDEAD,
+       0xFF0F0740, 0xABCD,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00005B8B,
+               0x036, 0x0000DB8B,
+               0x036, 0x00015B8B,
+               0x036, 0x0001DB8B,
+               0x036, 0x000262DB,
+               0x036, 0x0002E2DB,
+               0x036, 0x000362DB,
+               0x036, 0x0003E2DB,
+               0x036, 0x0004553B,
+               0x036, 0x0004D53B,
+               0x036, 0x0005553B,
+               0x036, 0x0005D53B,
+       0xFF0F01C0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00005B8B,
+               0x036, 0x0000DB8B,
+               0x036, 0x00015B8B,
+               0x036, 0x0001DB8B,
+               0x036, 0x000262DB,
+               0x036, 0x0002E2DB,
+               0x036, 0x000362DB,
+               0x036, 0x0003E2DB,
+               0x036, 0x0004553B,
+               0x036, 0x0004D53B,
+               0x036, 0x0005553B,
+               0x036, 0x0005D53B,
+       0xFF0F02C0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00005B8B,
+               0x036, 0x0000DB8B,
+               0x036, 0x00015B8B,
+               0x036, 0x0001DB8B,
+               0x036, 0x000262DB,
+               0x036, 0x0002E2DB,
+               0x036, 0x000362DB,
+               0x036, 0x0003E2DB,
+               0x036, 0x0004553B,
+               0x036, 0x0004D53B,
+               0x036, 0x0005553B,
+               0x036, 0x0005D53B,
+       0xFF0F07D8, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00005B8B,
+               0x036, 0x0000DB8B,
+               0x036, 0x00015B8B,
+               0x036, 0x0001DB8B,
+               0x036, 0x000262DB,
+               0x036, 0x0002E2DB,
+               0x036, 0x000362DB,
+               0x036, 0x0003E2DB,
+               0x036, 0x0004553B,
+               0x036, 0x0004D53B,
+               0x036, 0x0005553B,
+               0x036, 0x0005D53B,
+       0xFF0F07D0, 0xCDEF,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00005B8B,
+               0x036, 0x0000DB8B,
+               0x036, 0x00015B8B,
+               0x036, 0x0001DB8B,
+               0x036, 0x000262DB,
+               0x036, 0x0002E2DB,
+               0x036, 0x000362DB,
+               0x036, 0x0003E2DB,
+               0x036, 0x0004553B,
+               0x036, 0x0004D53B,
+               0x036, 0x0005553B,
+               0x036, 0x0005D53B,
+       0xCDCDCDCD, 0xCDCD,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+               0x036, 0x00084EB4,
+               0x036, 0x0008C9B4,
+               0x036, 0x000949B4,
+               0x036, 0x0009C9B4,
+               0x036, 0x000A4935,
+               0x036, 0x000AC935,
+               0x036, 0x000B4935,
+               0x036, 0x000BC935,
+               0x036, 0x000C4EB4,
+               0x036, 0x000CCEB4,
+               0x036, 0x000D4EB4,
+               0x036, 0x000DCEB4,
+       0xFF0F0740, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x0EF, 0x00000008,
+       0xFF0F0740, 0xABCD,
+               0x03C, 0x000002DC,
+               0x03C, 0x00000524,
+               0x03C, 0x00000902,
+       0xFF0F01C0, 0xCDEF,
+               0x03C, 0x000002DC,
+               0x03C, 0x00000524,
+               0x03C, 0x00000902,
+       0xFF0F02C0, 0xCDEF,
+               0x03C, 0x000002DC,
+               0x03C, 0x00000524,
+               0x03C, 0x00000902,
+       0xFF0F07D8, 0xCDEF,
+               0x03C, 0x000002DC,
+               0x03C, 0x00000524,
+               0x03C, 0x00000902,
+       0xFF0F07D0, 0xCDEF,
+               0x03C, 0x000002DC,
+               0x03C, 0x00000524,
+               0x03C, 0x00000902,
+       0xCDCDCDCD, 0xCDCD,
+               0x03C, 0x000002AA,
+               0x03C, 0x000005A2,
+               0x03C, 0x00000880,
+       0xFF0F0740, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000002,
+               0x0DF, 0x00000080,
+       0xFF0F0740, 0xABCD,
+               0x061, 0x000EAC43,
+               0x062, 0x00038F47,
+               0x063, 0x00031157,
+               0x064, 0x0001C4AC,
+               0x065, 0x000931D1,
+       0xFF0F01C0, 0xCDEF,
+               0x061, 0x000EAC43,
+               0x062, 0x00038F47,
+               0x063, 0x00031157,
+               0x064, 0x0001C4AC,
+               0x065, 0x000931D1,
+       0xFF0F02C0, 0xCDEF,
+               0x061, 0x000EAC43,
+               0x062, 0x00038F47,
+               0x063, 0x00031157,
+               0x064, 0x0001C4AC,
+               0x065, 0x000931D1,
+       0xFF0F07D8, 0xCDEF,
+               0x061, 0x000EAC43,
+               0x062, 0x00038F47,
+               0x063, 0x00031157,
+               0x064, 0x0001C4AC,
+               0x065, 0x000931D1,
+       0xFF0F07D0, 0xCDEF,
+               0x061, 0x000EAC43,
+               0x062, 0x00038F47,
+               0x063, 0x00031157,
+               0x064, 0x0001C4AC,
+               0x065, 0x000931D1,
+       0xCDCDCDCD, 0xCDCD,
+               0x061, 0x000E5D53,
+               0x062, 0x00038FCD,
+               0x063, 0x000314EB,
+               0x064, 0x000196AC,
+               0x065, 0x000931D7,
+       0xFF0F0740, 0xDEAD,
+               0x008, 0x00008400,
+};
+
+u32 RTL8821AE_RADIOA_ARRAY[] = {
+               0x018, 0x0001712A,
+               0x056, 0x00051CF2,
+               0x066, 0x00040000,
+               0x000, 0x00010000,
+               0x01E, 0x00080000,
+               0x082, 0x00000830,
+               0x083, 0x00021800,
+               0x084, 0x00028000,
+               0x085, 0x00048000,
+               0x086, 0x00094838,
+               0x087, 0x00044980,
+               0x088, 0x00048000,
+               0x089, 0x0000D480,
+               0x08A, 0x00042240,
+               0x08B, 0x000F0380,
+               0x08C, 0x00090000,
+               0x08D, 0x00022852,
+               0x08E, 0x00065540,
+               0x08F, 0x00088001,
+               0x0EF, 0x00020000,
+               0x03E, 0x00000380,
+               0x03F, 0x00090018,
+               0x03E, 0x00020380,
+               0x03F, 0x000A0018,
+               0x03E, 0x00040308,
+               0x03F, 0x000A0018,
+               0x03E, 0x00060018,
+               0x03F, 0x000A0018,
+               0x0EF, 0x00000000,
+               0x018, 0x0001712A,
+               0x089, 0x00000080,
+               0x08B, 0x00080180,
+               0x0EF, 0x00001000,
+               0x03A, 0x00000244,
+               0x03B, 0x00038027,
+               0x03C, 0x00082000,
+               0x03A, 0x00000244,
+               0x03B, 0x00030113,
+               0x03C, 0x00082000,
+               0x03A, 0x0000014C,
+               0x03B, 0x00028027,
+               0x03C, 0x00082000,
+               0x03A, 0x000000CC,
+               0x03B, 0x00027027,
+               0x03C, 0x00042000,
+               0x03A, 0x0000014C,
+               0x03B, 0x0001F913,
+               0x03C, 0x00042000,
+               0x03A, 0x0000010C,
+               0x03B, 0x00017F10,
+               0x03C, 0x00012000,
+               0x03A, 0x000000D0,
+               0x03B, 0x00008027,
+               0x03C, 0x000CA000,
+               0x03A, 0x00000244,
+               0x03B, 0x00078027,
+               0x03C, 0x00082000,
+               0x03A, 0x00000244,
+               0x03B, 0x00070113,
+               0x03C, 0x00082000,
+               0x03A, 0x0000014C,
+               0x03B, 0x00068027,
+               0x03C, 0x00082000,
+               0x03A, 0x000000CC,
+               0x03B, 0x00067027,
+               0x03C, 0x00042000,
+               0x03A, 0x0000014C,
+               0x03B, 0x0005F913,
+               0x03C, 0x00042000,
+               0x03A, 0x0000010C,
+               0x03B, 0x00057F10,
+               0x03C, 0x00012000,
+               0x03A, 0x000000D0,
+               0x03B, 0x00048027,
+               0x03C, 0x000CA000,
+               0x03A, 0x00000244,
+               0x03B, 0x000B8027,
+               0x03C, 0x00082000,
+               0x03A, 0x00000244,
+               0x03B, 0x000B0113,
+               0x03C, 0x00082000,
+               0x03A, 0x0000014C,
+               0x03B, 0x000A8027,
+               0x03C, 0x00082000,
+               0x03A, 0x000000CC,
+               0x03B, 0x000A7027,
+               0x03C, 0x00042000,
+               0x03A, 0x0000014C,
+               0x03B, 0x0009F913,
+               0x03C, 0x00042000,
+               0x03A, 0x0000010C,
+               0x03B, 0x00097F10,
+               0x03C, 0x00012000,
+               0x03A, 0x000000D0,
+               0x03B, 0x00088027,
+               0x03C, 0x000CA000,
+               0x0EF, 0x00000000,
+               0x0EF, 0x00001100,
+       0xFF0F0104, 0xABCD,
+               0x034, 0x0004ADF3,
+               0x034, 0x00049DF0,
+       0xFF0F0204, 0xCDEF,
+               0x034, 0x0004ADF3,
+               0x034, 0x00049DF0,
+       0xFF0F0404, 0xCDEF,
+               0x034, 0x0004ADF3,
+               0x034, 0x00049DF0,
+       0xFF0F0200, 0xCDEF,
+               0x034, 0x0004ADF5,
+               0x034, 0x00049DF2,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0004A0F3,
+               0x034, 0x000490B1,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0004ADF7,
+               0x034, 0x00049DF3,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F0104, 0xABCD,
+               0x034, 0x00048DED,
+               0x034, 0x00047DEA,
+               0x034, 0x00046DE7,
+               0x034, 0x00045CE9,
+               0x034, 0x00044CE6,
+               0x034, 0x000438C6,
+               0x034, 0x00042886,
+               0x034, 0x00041486,
+               0x034, 0x00040447,
+       0xFF0F0204, 0xCDEF,
+               0x034, 0x00048DED,
+               0x034, 0x00047DEA,
+               0x034, 0x00046DE7,
+               0x034, 0x00045CE9,
+               0x034, 0x00044CE6,
+               0x034, 0x000438C6,
+               0x034, 0x00042886,
+               0x034, 0x00041486,
+               0x034, 0x00040447,
+       0xFF0F0404, 0xCDEF,
+               0x034, 0x00048DED,
+               0x034, 0x00047DEA,
+               0x034, 0x00046DE7,
+               0x034, 0x00045CE9,
+               0x034, 0x00044CE6,
+               0x034, 0x000438C6,
+               0x034, 0x00042886,
+               0x034, 0x00041486,
+               0x034, 0x00040447,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x000480AE,
+               0x034, 0x000470AB,
+               0x034, 0x0004608B,
+               0x034, 0x00045069,
+               0x034, 0x00044048,
+               0x034, 0x00043045,
+               0x034, 0x00042026,
+               0x034, 0x00041023,
+               0x034, 0x00040002,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x00048DEF,
+               0x034, 0x00047DEC,
+               0x034, 0x00046DE9,
+               0x034, 0x00045CCB,
+               0x034, 0x0004488D,
+               0x034, 0x0004348D,
+               0x034, 0x0004248A,
+               0x034, 0x0004108D,
+               0x034, 0x0004008A,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F0200, 0xABCD,
+               0x034, 0x0002ADF4,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0002A0F3,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0002ADF7,
+       0xFF0F0200, 0xDEAD,
+       0xFF0F0104, 0xABCD,
+               0x034, 0x00029DF4,
+       0xFF0F0204, 0xCDEF,
+               0x034, 0x00029DF4,
+       0xFF0F0404, 0xCDEF,
+               0x034, 0x00029DF4,
+       0xFF0F0200, 0xCDEF,
+               0x034, 0x00029DF1,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x000290F0,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x00029DF2,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F0104, 0xABCD,
+               0x034, 0x00028DF1,
+               0x034, 0x00027DEE,
+               0x034, 0x00026DEB,
+               0x034, 0x00025CEC,
+               0x034, 0x00024CE9,
+               0x034, 0x000238CA,
+               0x034, 0x00022889,
+               0x034, 0x00021489,
+               0x034, 0x0002044A,
+       0xFF0F0204, 0xCDEF,
+               0x034, 0x00028DF1,
+               0x034, 0x00027DEE,
+               0x034, 0x00026DEB,
+               0x034, 0x00025CEC,
+               0x034, 0x00024CE9,
+               0x034, 0x000238CA,
+               0x034, 0x00022889,
+               0x034, 0x00021489,
+               0x034, 0x0002044A,
+       0xFF0F0404, 0xCDEF,
+               0x034, 0x00028DF1,
+               0x034, 0x00027DEE,
+               0x034, 0x00026DEB,
+               0x034, 0x00025CEC,
+               0x034, 0x00024CE9,
+               0x034, 0x000238CA,
+               0x034, 0x00022889,
+               0x034, 0x00021489,
+               0x034, 0x0002044A,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x000280AF,
+               0x034, 0x000270AC,
+               0x034, 0x0002608B,
+               0x034, 0x00025069,
+               0x034, 0x00024048,
+               0x034, 0x00023045,
+               0x034, 0x00022026,
+               0x034, 0x00021023,
+               0x034, 0x00020002,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x00028DEE,
+               0x034, 0x00027DEB,
+               0x034, 0x00026CCD,
+               0x034, 0x00025CCA,
+               0x034, 0x0002488C,
+               0x034, 0x0002384C,
+               0x034, 0x00022849,
+               0x034, 0x00021449,
+               0x034, 0x0002004D,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F02C0, 0xABCD,
+               0x034, 0x0000A0D7,
+               0x034, 0x000090D3,
+               0x034, 0x000080B1,
+               0x034, 0x000070AE,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x0000ADF7,
+               0x034, 0x00009DF4,
+               0x034, 0x00008DF1,
+               0x034, 0x00007DEE,
+       0xFF0F02C0, 0xDEAD,
+       0xFF0F0104, 0xABCD,
+               0x034, 0x00006DEB,
+               0x034, 0x00005CEC,
+               0x034, 0x00004CE9,
+               0x034, 0x000038CA,
+               0x034, 0x00002889,
+               0x034, 0x00001489,
+               0x034, 0x0000044A,
+       0xFF0F0204, 0xCDEF,
+               0x034, 0x00006DEB,
+               0x034, 0x00005CEC,
+               0x034, 0x00004CE9,
+               0x034, 0x000038CA,
+               0x034, 0x00002889,
+               0x034, 0x00001489,
+               0x034, 0x0000044A,
+       0xFF0F0404, 0xCDEF,
+               0x034, 0x00006DEB,
+               0x034, 0x00005CEC,
+               0x034, 0x00004CE9,
+               0x034, 0x000038CA,
+               0x034, 0x00002889,
+               0x034, 0x00001489,
+               0x034, 0x0000044A,
+       0xFF0F02C0, 0xCDEF,
+               0x034, 0x0000608D,
+               0x034, 0x0000506B,
+               0x034, 0x0000404A,
+               0x034, 0x00003047,
+               0x034, 0x00002044,
+               0x034, 0x00001025,
+               0x034, 0x00000004,
+       0xCDCDCDCD, 0xCDCD,
+               0x034, 0x00006DCD,
+               0x034, 0x00005CCD,
+               0x034, 0x00004CCA,
+               0x034, 0x0000388C,
+               0x034, 0x00002888,
+               0x034, 0x00001488,
+               0x034, 0x00000486,
+       0xFF0F0104, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000040,
+       0xFF0F0104, 0xABCD,
+               0x035, 0x00000187,
+               0x035, 0x00008187,
+               0x035, 0x00010187,
+               0x035, 0x00020188,
+               0x035, 0x00028188,
+               0x035, 0x00030188,
+               0x035, 0x00040188,
+               0x035, 0x00048188,
+               0x035, 0x00050188,
+       0xFF0F0204, 0xCDEF,
+               0x035, 0x00000187,
+               0x035, 0x00008187,
+               0x035, 0x00010187,
+               0x035, 0x00020188,
+               0x035, 0x00028188,
+               0x035, 0x00030188,
+               0x035, 0x00040188,
+               0x035, 0x00048188,
+               0x035, 0x00050188,
+       0xFF0F0404, 0xCDEF,
+               0x035, 0x00000187,
+               0x035, 0x00008187,
+               0x035, 0x00010187,
+               0x035, 0x00020188,
+               0x035, 0x00028188,
+               0x035, 0x00030188,
+               0x035, 0x00040188,
+               0x035, 0x00048188,
+               0x035, 0x00050188,
+       0xCDCDCDCD, 0xCDCD,
+               0x035, 0x00000145,
+               0x035, 0x00008145,
+               0x035, 0x00010145,
+               0x035, 0x00020196,
+               0x035, 0x00028196,
+               0x035, 0x00030196,
+               0x035, 0x000401C7,
+               0x035, 0x000481C7,
+               0x035, 0x000501C7,
+       0xFF0F0104, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000010,
+       0xFF0F0104, 0xABCD,
+               0x036, 0x00085733,
+               0x036, 0x0008D733,
+               0x036, 0x00095733,
+               0x036, 0x0009D733,
+               0x036, 0x000A64B4,
+               0x036, 0x000AE4B4,
+               0x036, 0x000B64B4,
+               0x036, 0x000BE4B4,
+               0x036, 0x000C64B4,
+               0x036, 0x000CE4B4,
+               0x036, 0x000D64B4,
+               0x036, 0x000DE4B4,
+       0xFF0F0204, 0xCDEF,
+               0x036, 0x00085733,
+               0x036, 0x0008D733,
+               0x036, 0x00095733,
+               0x036, 0x0009D733,
+               0x036, 0x000A64B4,
+               0x036, 0x000AE4B4,
+               0x036, 0x000B64B4,
+               0x036, 0x000BE4B4,
+               0x036, 0x000C64B4,
+               0x036, 0x000CE4B4,
+               0x036, 0x000D64B4,
+               0x036, 0x000DE4B4,
+       0xFF0F0404, 0xCDEF,
+               0x036, 0x00085733,
+               0x036, 0x0008D733,
+               0x036, 0x00095733,
+               0x036, 0x0009D733,
+               0x036, 0x000A64B4,
+               0x036, 0x000AE4B4,
+               0x036, 0x000B64B4,
+               0x036, 0x000BE4B4,
+               0x036, 0x000C64B4,
+               0x036, 0x000CE4B4,
+               0x036, 0x000D64B4,
+               0x036, 0x000DE4B4,
+       0xCDCDCDCD, 0xCDCD,
+               0x036, 0x000056B3,
+               0x036, 0x0000D6B3,
+               0x036, 0x000156B3,
+               0x036, 0x0001D6B3,
+               0x036, 0x00026634,
+               0x036, 0x0002E634,
+               0x036, 0x00036634,
+               0x036, 0x0003E634,
+               0x036, 0x000467B4,
+               0x036, 0x0004E7B4,
+               0x036, 0x000567B4,
+               0x036, 0x0005E7B4,
+       0xFF0F0104, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x0EF, 0x00000008,
+       0xFF0F0104, 0xABCD,
+               0x03C, 0x000001C8,
+               0x03C, 0x00000492,
+       0xFF0F0204, 0xCDEF,
+               0x03C, 0x000001C8,
+               0x03C, 0x00000492,
+       0xFF0F0404, 0xCDEF,
+               0x03C, 0x000001C8,
+               0x03C, 0x00000492,
+       0xCDCDCDCD, 0xCDCD,
+               0x03C, 0x0000022A,
+               0x03C, 0x00000594,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F0104, 0xABCD,
+               0x03C, 0x00000800,
+       0xFF0F0204, 0xCDEF,
+               0x03C, 0x00000800,
+       0xFF0F0404, 0xCDEF,
+               0x03C, 0x00000800,
+       0xFF0F02C0, 0xCDEF,
+               0x03C, 0x00000820,
+       0xCDCDCDCD, 0xCDCD,
+               0x03C, 0x00000900,
+       0xFF0F0104, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x018, 0x0001712A,
+               0x0EF, 0x00000002,
+       0xFF0F0104, 0xABCD,
+               0x008, 0x0004E400,
+       0xFF0F0204, 0xCDEF,
+               0x008, 0x0004E400,
+       0xFF0F0404, 0xCDEF,
+               0x008, 0x0004E400,
+       0xCDCDCDCD, 0xCDCD,
+               0x008, 0x00002000,
+       0xFF0F0104, 0xDEAD,
+               0x0EF, 0x00000000,
+               0x0DF, 0x000000C0,
+               0x01F, 0x00040064,
+       0xFF0F0104, 0xABCD,
+               0x058, 0x000A7284,
+               0x059, 0x000600EC,
+       0xFF0F0204, 0xCDEF,
+               0x058, 0x000A7284,
+               0x059, 0x000600EC,
+       0xFF0F0404, 0xCDEF,
+               0x058, 0x000A7284,
+               0x059, 0x000600EC,
+       0xCDCDCDCD, 0xCDCD,
+               0x058, 0x00081184,
+               0x059, 0x0006016C,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F0104, 0xABCD,
+               0x061, 0x000E8D73,
+               0x062, 0x00093FC5,
+       0xFF0F0204, 0xCDEF,
+               0x061, 0x000E8D73,
+               0x062, 0x00093FC5,
+       0xFF0F0404, 0xCDEF,
+               0x061, 0x000E8D73,
+               0x062, 0x00093FC5,
+       0xCDCDCDCD, 0xCDCD,
+               0x061, 0x000EAD53,
+               0x062, 0x00093BC4,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F0104, 0xABCD,
+               0x063, 0x000110E9,
+       0xFF0F0204, 0xCDEF,
+               0x063, 0x000110E9,
+       0xFF0F0404, 0xCDEF,
+               0x063, 0x000110E9,
+       0xFF0F0200, 0xCDEF,
+               0x063, 0x000710E9,
+       0xFF0F02C0, 0xCDEF,
+               0x063, 0x000110E9,
+       0xCDCDCDCD, 0xCDCD,
+               0x063, 0x000714E9,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F0104, 0xABCD,
+               0x064, 0x0001C27C,
+       0xFF0F0204, 0xCDEF,
+               0x064, 0x0001C27C,
+       0xFF0F0404, 0xCDEF,
+               0x064, 0x0001C27C,
+       0xCDCDCDCD, 0xCDCD,
+               0x064, 0x0001C67C,
+       0xFF0F0104, 0xDEAD,
+       0xFF0F0200, 0xABCD,
+               0x065, 0x00093016,
+       0xFF0F02C0, 0xCDEF,
+               0x065, 0x00093015,
+       0xCDCDCDCD, 0xCDCD,
+               0x065, 0x00091016,
+       0xFF0F0200, 0xDEAD,
+               0x018, 0x00000006,
+               0x0EF, 0x00002000,
+               0x03B, 0x0003824B,
+               0x03B, 0x0003024B,
+               0x03B, 0x0002844B,
+               0x03B, 0x00020F4B,
+               0x03B, 0x00018F4B,
+               0x03B, 0x000104B2,
+               0x03B, 0x00008049,
+               0x03B, 0x00000148,
+               0x03B, 0x0007824B,
+               0x03B, 0x0007024B,
+               0x03B, 0x0006824B,
+               0x03B, 0x00060F4B,
+               0x03B, 0x00058F4B,
+               0x03B, 0x000504B2,
+               0x03B, 0x00048049,
+               0x03B, 0x00040148,
+               0x0EF, 0x00000000,
+               0x0EF, 0x00000100,
+               0x034, 0x0000ADF3,
+               0x034, 0x00009DEF,
+               0x034, 0x00008DEC,
+               0x034, 0x00007DE9,
+               0x034, 0x00006CED,
+               0x034, 0x00005CE9,
+               0x034, 0x000044E9,
+               0x034, 0x000034E6,
+               0x034, 0x0000246A,
+               0x034, 0x00001467,
+               0x034, 0x00000068,
+               0x0EF, 0x00000000,
+               0x0ED, 0x00000010,
+               0x044, 0x0000ADF2,
+               0x044, 0x00009DEF,
+               0x044, 0x00008DEC,
+               0x044, 0x00007DE9,
+               0x044, 0x00006CEC,
+               0x044, 0x00005CE9,
+               0x044, 0x000044EC,
+               0x044, 0x000034E9,
+               0x044, 0x0000246C,
+               0x044, 0x00001469,
+               0x044, 0x0000006C,
+               0x0ED, 0x00000000,
+               0x0ED, 0x00000001,
+               0x040, 0x00038DA7,
+               0x040, 0x000300C2,
+               0x040, 0x000288E2,
+               0x040, 0x000200B8,
+               0x040, 0x000188A5,
+               0x040, 0x00010FBC,
+               0x040, 0x00008F71,
+               0x040, 0x00000240,
+               0x0ED, 0x00000000,
+               0x0EF, 0x000020A2,
+               0x0DF, 0x00000080,
+               0x035, 0x00000120,
+               0x035, 0x00008120,
+               0x035, 0x00010120,
+               0x036, 0x00000085,
+               0x036, 0x00008085,
+               0x036, 0x00010085,
+               0x036, 0x00018085,
+               0x0EF, 0x00000000,
+               0x051, 0x00000C31,
+               0x052, 0x00000622,
+               0x053, 0x000FC70B,
+               0x054, 0x0000017E,
+               0x056, 0x00051DF3,
+               0x051, 0x00000C01,
+               0x052, 0x000006D6,
+               0x053, 0x000FC649,
+               0x070, 0x00049661,
+               0x071, 0x0007843E,
+               0x072, 0x00000382,
+               0x074, 0x00051400,
+               0x035, 0x00000160,
+               0x035, 0x00008160,
+               0x035, 0x00010160,
+               0x036, 0x00000124,
+               0x036, 0x00008124,
+               0x036, 0x00010124,
+               0x036, 0x00018124,
+               0x0ED, 0x0000000C,
+               0x045, 0x00000140,
+               0x045, 0x00008140,
+               0x045, 0x00010140,
+               0x046, 0x00000124,
+               0x046, 0x00008124,
+               0x046, 0x00010124,
+               0x046, 0x00018124,
+               0x0DF, 0x00000088,
+               0x0B3, 0x000F0E18,
+               0x0B4, 0x0001214C,
+               0x0B7, 0x0003000C,
+               0x01C, 0x000539D2,
+               0x018, 0x0001F12A,
+               0x0FE, 0x00000000,
+               0x0FE, 0x00000000,
+               0x018, 0x0001712A,
+};
+
+u32 RTL8812AE_MAC_REG_ARRAY[] = {
+               0x010, 0x0000000C,
+       0xFF0F0180, 0xABCD,
+               0x025, 0x0000000F,
+       0xFF0F01C0, 0xCDEF,
+               0x025, 0x0000000F,
+       0xCDCDCDCD, 0xCDCD,
+               0x025, 0x0000006F,
+       0xFF0F0180, 0xDEAD,
+               0x072, 0x00000000,
+               0x428, 0x0000000A,
+               0x429, 0x00000010,
+               0x430, 0x00000000,
+               0x431, 0x00000000,
+               0x432, 0x00000000,
+               0x433, 0x00000001,
+               0x434, 0x00000004,
+               0x435, 0x00000005,
+               0x436, 0x00000007,
+               0x437, 0x00000008,
+               0x43C, 0x00000004,
+               0x43D, 0x00000005,
+               0x43E, 0x00000007,
+               0x43F, 0x00000008,
+               0x440, 0x0000005D,
+               0x441, 0x00000001,
+               0x442, 0x00000000,
+               0x444, 0x00000010,
+               0x445, 0x00000000,
+               0x446, 0x00000000,
+               0x447, 0x00000000,
+               0x448, 0x00000000,
+               0x449, 0x000000F0,
+               0x44A, 0x0000000F,
+               0x44B, 0x0000003E,
+               0x44C, 0x00000010,
+               0x44D, 0x00000000,
+               0x44E, 0x00000000,
+               0x44F, 0x00000000,
+               0x450, 0x00000000,
+               0x451, 0x000000F0,
+               0x452, 0x0000000F,
+               0x453, 0x00000000,
+               0x45B, 0x00000080,
+               0x460, 0x00000066,
+               0x461, 0x00000066,
+               0x4C8, 0x000000FF,
+               0x4C9, 0x00000008,
+               0x4CC, 0x000000FF,
+               0x4CD, 0x000000FF,
+               0x4CE, 0x00000001,
+               0x500, 0x00000026,
+               0x501, 0x000000A2,
+               0x502, 0x0000002F,
+               0x503, 0x00000000,
+               0x504, 0x00000028,
+               0x505, 0x000000A3,
+               0x506, 0x0000005E,
+               0x507, 0x00000000,
+               0x508, 0x0000002B,
+               0x509, 0x000000A4,
+               0x50A, 0x0000005E,
+               0x50B, 0x00000000,
+               0x50C, 0x0000004F,
+               0x50D, 0x000000A4,
+               0x50E, 0x00000000,
+               0x50F, 0x00000000,
+               0x512, 0x0000001C,
+               0x514, 0x0000000A,
+               0x516, 0x0000000A,
+               0x525, 0x0000004F,
+               0x550, 0x00000010,
+               0x551, 0x00000010,
+               0x559, 0x00000002,
+               0x55C, 0x00000050,
+               0x55D, 0x000000FF,
+               0x604, 0x00000001,
+               0x605, 0x00000030,
+               0x607, 0x00000003,
+               0x608, 0x0000000E,
+               0x609, 0x0000002A,
+               0x620, 0x000000FF,
+               0x621, 0x000000FF,
+               0x622, 0x000000FF,
+               0x623, 0x000000FF,
+               0x624, 0x000000FF,
+               0x625, 0x000000FF,
+               0x626, 0x000000FF,
+               0x627, 0x000000FF,
+               0x638, 0x00000050,
+               0x63C, 0x0000000A,
+               0x63D, 0x0000000A,
+               0x63E, 0x0000000E,
+               0x63F, 0x0000000E,
+               0x640, 0x00000080,
+               0x642, 0x00000040,
+               0x643, 0x00000000,
+               0x652, 0x000000C8,
+               0x66E, 0x00000005,
+               0x700, 0x00000021,
+               0x701, 0x00000043,
+               0x702, 0x00000065,
+               0x703, 0x00000087,
+               0x708, 0x00000021,
+               0x709, 0x00000043,
+               0x70A, 0x00000065,
+               0x70B, 0x00000087,
+               0x718, 0x00000040,
+};
+
+u32 RTL8821AE_MAC_REG_ARRAY[] = {
+               0x428, 0x0000000A,
+               0x429, 0x00000010,
+               0x430, 0x00000000,
+               0x431, 0x00000000,
+               0x432, 0x00000000,
+               0x433, 0x00000001,
+               0x434, 0x00000004,
+               0x435, 0x00000005,
+               0x436, 0x00000007,
+               0x437, 0x00000008,
+               0x43C, 0x00000004,
+               0x43D, 0x00000005,
+               0x43E, 0x00000007,
+               0x43F, 0x00000008,
+               0x440, 0x0000005D,
+               0x441, 0x00000001,
+               0x442, 0x00000000,
+               0x444, 0x00000010,
+               0x445, 0x00000000,
+               0x446, 0x00000000,
+               0x447, 0x00000000,
+               0x448, 0x00000000,
+               0x449, 0x000000F0,
+               0x44A, 0x0000000F,
+               0x44B, 0x0000003E,
+               0x44C, 0x00000010,
+               0x44D, 0x00000000,
+               0x44E, 0x00000000,
+               0x44F, 0x00000000,
+               0x450, 0x00000000,
+               0x451, 0x000000F0,
+               0x452, 0x0000000F,
+               0x453, 0x00000000,
+               0x456, 0x0000005E,
+               0x460, 0x00000066,
+               0x461, 0x00000066,
+               0x4C8, 0x0000003F,
+               0x4C9, 0x000000FF,
+               0x4CC, 0x000000FF,
+               0x4CD, 0x000000FF,
+               0x4CE, 0x00000001,
+               0x500, 0x00000026,
+               0x501, 0x000000A2,
+               0x502, 0x0000002F,
+               0x503, 0x00000000,
+               0x504, 0x00000028,
+               0x505, 0x000000A3,
+               0x506, 0x0000005E,
+               0x507, 0x00000000,
+               0x508, 0x0000002B,
+               0x509, 0x000000A4,
+               0x50A, 0x0000005E,
+               0x50B, 0x00000000,
+               0x50C, 0x0000004F,
+               0x50D, 0x000000A4,
+               0x50E, 0x00000000,
+               0x50F, 0x00000000,
+               0x512, 0x0000001C,
+               0x514, 0x0000000A,
+               0x516, 0x0000000A,
+               0x525, 0x0000004F,
+               0x550, 0x00000010,
+               0x551, 0x00000010,
+               0x559, 0x00000002,
+               0x55C, 0x00000050,
+               0x55D, 0x000000FF,
+               0x605, 0x00000030,
+               0x607, 0x00000007,
+               0x608, 0x0000000E,
+               0x609, 0x0000002A,
+               0x620, 0x000000FF,
+               0x621, 0x000000FF,
+               0x622, 0x000000FF,
+               0x623, 0x000000FF,
+               0x624, 0x000000FF,
+               0x625, 0x000000FF,
+               0x626, 0x000000FF,
+               0x627, 0x000000FF,
+               0x638, 0x00000050,
+               0x63C, 0x0000000A,
+               0x63D, 0x0000000A,
+               0x63E, 0x0000000E,
+               0x63F, 0x0000000E,
+               0x640, 0x00000040,
+               0x642, 0x00000040,
+               0x643, 0x00000000,
+               0x652, 0x000000C8,
+               0x66E, 0x00000005,
+               0x700, 0x00000021,
+               0x701, 0x00000043,
+               0x702, 0x00000065,
+               0x703, 0x00000087,
+               0x708, 0x00000021,
+               0x709, 0x00000043,
+               0x70A, 0x00000065,
+               0x70B, 0x00000087,
+               0x718, 0x00000040,
+};
+
+u32 RTL8812AE_AGC_TAB_ARRAY[] = {
+       0xFF0F07D8, 0xABCD,
+               0x81C, 0xFC000001,
+               0x81C, 0xFB020001,
+               0x81C, 0xFA040001,
+               0x81C, 0xF9060001,
+               0x81C, 0xF8080001,
+               0x81C, 0xF70A0001,
+               0x81C, 0xF60C0001,
+               0x81C, 0xF50E0001,
+               0x81C, 0xF4100001,
+               0x81C, 0xF3120001,
+               0x81C, 0xF2140001,
+               0x81C, 0xF1160001,
+               0x81C, 0xF0180001,
+               0x81C, 0xEF1A0001,
+               0x81C, 0xEE1C0001,
+               0x81C, 0xED1E0001,
+               0x81C, 0xEC200001,
+               0x81C, 0xEB220001,
+               0x81C, 0xEA240001,
+               0x81C, 0xCD260001,
+               0x81C, 0xCC280001,
+               0x81C, 0xCB2A0001,
+               0x81C, 0xCA2C0001,
+               0x81C, 0xC92E0001,
+               0x81C, 0xC8300001,
+               0x81C, 0xA6320001,
+               0x81C, 0xA5340001,
+               0x81C, 0xA4360001,
+               0x81C, 0xA3380001,
+               0x81C, 0xA23A0001,
+               0x81C, 0x883C0001,
+               0x81C, 0x873E0001,
+               0x81C, 0x86400001,
+               0x81C, 0x85420001,
+               0x81C, 0x84440001,
+               0x81C, 0x83460001,
+               0x81C, 0x82480001,
+               0x81C, 0x814A0001,
+               0x81C, 0x484C0001,
+               0x81C, 0x474E0001,
+               0x81C, 0x46500001,
+               0x81C, 0x45520001,
+               0x81C, 0x44540001,
+               0x81C, 0x43560001,
+               0x81C, 0x42580001,
+               0x81C, 0x415A0001,
+               0x81C, 0x255C0001,
+               0x81C, 0x245E0001,
+               0x81C, 0x23600001,
+               0x81C, 0x22620001,
+               0x81C, 0x21640001,
+               0x81C, 0x21660001,
+               0x81C, 0x21680001,
+               0x81C, 0x216A0001,
+               0x81C, 0x216C0001,
+               0x81C, 0x216E0001,
+               0x81C, 0x21700001,
+               0x81C, 0x21720001,
+               0x81C, 0x21740001,
+               0x81C, 0x21760001,
+               0x81C, 0x21780001,
+               0x81C, 0x217A0001,
+               0x81C, 0x217C0001,
+               0x81C, 0x217E0001,
+       0xFF0F07D0, 0xCDEF,
+               0x81C, 0xF9000001,
+               0x81C, 0xF8020001,
+               0x81C, 0xF7040001,
+               0x81C, 0xF6060001,
+               0x81C, 0xF5080001,
+               0x81C, 0xF40A0001,
+               0x81C, 0xF30C0001,
+               0x81C, 0xF20E0001,
+               0x81C, 0xF1100001,
+               0x81C, 0xF0120001,
+               0x81C, 0xEF140001,
+               0x81C, 0xEE160001,
+               0x81C, 0xED180001,
+               0x81C, 0xEC1A0001,
+               0x81C, 0xEB1C0001,
+               0x81C, 0xEA1E0001,
+               0x81C, 0xCD200001,
+               0x81C, 0xCC220001,
+               0x81C, 0xCB240001,
+               0x81C, 0xCA260001,
+               0x81C, 0xC9280001,
+               0x81C, 0xC82A0001,
+               0x81C, 0xC72C0001,
+               0x81C, 0xC62E0001,
+               0x81C, 0xA5300001,
+               0x81C, 0xA4320001,
+               0x81C, 0xA3340001,
+               0x81C, 0xA2360001,
+               0x81C, 0x88380001,
+               0x81C, 0x873A0001,
+               0x81C, 0x863C0001,
+               0x81C, 0x853E0001,
+               0x81C, 0x84400001,
+               0x81C, 0x83420001,
+               0x81C, 0x82440001,
+               0x81C, 0x81460001,
+               0x81C, 0x48480001,
+               0x81C, 0x474A0001,
+               0x81C, 0x464C0001,
+               0x81C, 0x454E0001,
+               0x81C, 0x44500001,
+               0x81C, 0x43520001,
+               0x81C, 0x42540001,
+               0x81C, 0x41560001,
+               0x81C, 0x25580001,
+               0x81C, 0x245A0001,
+               0x81C, 0x235C0001,
+               0x81C, 0x225E0001,
+               0x81C, 0x21600001,
+               0x81C, 0x21620001,
+               0x81C, 0x21640001,
+               0x81C, 0x21660001,
+               0x81C, 0x21680001,
+               0x81C, 0x216A0001,
+               0x81C, 0x236C0001,
+               0x81C, 0x226E0001,
+               0x81C, 0x21700001,
+               0x81C, 0x21720001,
+               0x81C, 0x21740001,
+               0x81C, 0x21760001,
+               0x81C, 0x21780001,
+               0x81C, 0x217A0001,
+               0x81C, 0x217C0001,
+               0x81C, 0x217E0001,
+       0xCDCDCDCD, 0xCDCD,
+               0x81C, 0xFF000001,
+               0x81C, 0xFF020001,
+               0x81C, 0xFF040001,
+               0x81C, 0xFF060001,
+               0x81C, 0xFF080001,
+               0x81C, 0xFE0A0001,
+               0x81C, 0xFD0C0001,
+               0x81C, 0xFC0E0001,
+               0x81C, 0xFB100001,
+               0x81C, 0xFA120001,
+               0x81C, 0xF9140001,
+               0x81C, 0xF8160001,
+               0x81C, 0xF7180001,
+               0x81C, 0xF61A0001,
+               0x81C, 0xF51C0001,
+               0x81C, 0xF41E0001,
+               0x81C, 0xF3200001,
+               0x81C, 0xF2220001,
+               0x81C, 0xF1240001,
+               0x81C, 0xF0260001,
+               0x81C, 0xEF280001,
+               0x81C, 0xEE2A0001,
+               0x81C, 0xED2C0001,
+               0x81C, 0xEC2E0001,
+               0x81C, 0xEB300001,
+               0x81C, 0xEA320001,
+               0x81C, 0xE9340001,
+               0x81C, 0xE8360001,
+               0x81C, 0xE7380001,
+               0x81C, 0xE63A0001,
+               0x81C, 0xE53C0001,
+               0x81C, 0xC73E0001,
+               0x81C, 0xC6400001,
+               0x81C, 0xC5420001,
+               0x81C, 0xC4440001,
+               0x81C, 0xC3460001,
+               0x81C, 0xC2480001,
+               0x81C, 0xC14A0001,
+               0x81C, 0xA74C0001,
+               0x81C, 0xA64E0001,
+               0x81C, 0xA5500001,
+               0x81C, 0xA4520001,
+               0x81C, 0xA3540001,
+               0x81C, 0xA2560001,
+               0x81C, 0xA1580001,
+               0x81C, 0x675A0001,
+               0x81C, 0x665C0001,
+               0x81C, 0x655E0001,
+               0x81C, 0x64600001,
+               0x81C, 0x63620001,
+               0x81C, 0x48640001,
+               0x81C, 0x47660001,
+               0x81C, 0x46680001,
+               0x81C, 0x456A0001,
+               0x81C, 0x446C0001,
+               0x81C, 0x436E0001,
+               0x81C, 0x42700001,
+               0x81C, 0x41720001,
+               0x81C, 0x41740001,
+               0x81C, 0x41760001,
+               0x81C, 0x41780001,
+               0x81C, 0x417A0001,
+               0x81C, 0x417C0001,
+               0x81C, 0x417E0001,
+       0xFF0F07D8, 0xDEAD,
+       0xFF0F0180, 0xABCD,
+               0x81C, 0xFC800001,
+               0x81C, 0xFB820001,
+               0x81C, 0xFA840001,
+               0x81C, 0xF9860001,
+               0x81C, 0xF8880001,
+               0x81C, 0xF78A0001,
+               0x81C, 0xF68C0001,
+               0x81C, 0xF58E0001,
+               0x81C, 0xF4900001,
+               0x81C, 0xF3920001,
+               0x81C, 0xF2940001,
+               0x81C, 0xF1960001,
+               0x81C, 0xF0980001,
+               0x81C, 0xEF9A0001,
+               0x81C, 0xEE9C0001,
+               0x81C, 0xED9E0001,
+               0x81C, 0xECA00001,
+               0x81C, 0xEBA20001,
+               0x81C, 0xEAA40001,
+               0x81C, 0xE9A60001,
+               0x81C, 0xE8A80001,
+               0x81C, 0xE7AA0001,
+               0x81C, 0xE6AC0001,
+               0x81C, 0xE5AE0001,
+               0x81C, 0xE4B00001,
+               0x81C, 0xE3B20001,
+               0x81C, 0xA8B40001,
+               0x81C, 0xA7B60001,
+               0x81C, 0xA6B80001,
+               0x81C, 0xA5BA0001,
+               0x81C, 0xA4BC0001,
+               0x81C, 0xA3BE0001,
+               0x81C, 0xA2C00001,
+               0x81C, 0xA1C20001,
+               0x81C, 0x68C40001,
+               0x81C, 0x67C60001,
+               0x81C, 0x66C80001,
+               0x81C, 0x65CA0001,
+               0x81C, 0x64CC0001,
+               0x81C, 0x47CE0001,
+               0x81C, 0x46D00001,
+               0x81C, 0x45D20001,
+               0x81C, 0x44D40001,
+               0x81C, 0x43D60001,
+               0x81C, 0x42D80001,
+               0x81C, 0x08DA0001,
+               0x81C, 0x07DC0001,
+               0x81C, 0x06DE0001,
+               0x81C, 0x05E00001,
+               0x81C, 0x04E20001,
+               0x81C, 0x03E40001,
+               0x81C, 0x02E60001,
+               0x81C, 0x01E80001,
+               0x81C, 0x01EA0001,
+               0x81C, 0x01EC0001,
+               0x81C, 0x01EE0001,
+               0x81C, 0x01F00001,
+               0x81C, 0x01F20001,
+               0x81C, 0x01F40001,
+               0x81C, 0x01F60001,
+               0x81C, 0x01F80001,
+               0x81C, 0x01FA0001,
+               0x81C, 0x01FC0001,
+               0x81C, 0x01FE0001,
+       0xFF0F0280, 0xCDEF,
+               0x81C, 0xFC800001,
+               0x81C, 0xFB820001,
+               0x81C, 0xFA840001,
+               0x81C, 0xF9860001,
+               0x81C, 0xF8880001,
+               0x81C, 0xF78A0001,
+               0x81C, 0xF68C0001,
+               0x81C, 0xF58E0001,
+               0x81C, 0xF4900001,
+               0x81C, 0xF3920001,
+               0x81C, 0xF2940001,
+               0x81C, 0xF1960001,
+               0x81C, 0xF0980001,
+               0x81C, 0xEF9A0001,
+               0x81C, 0xEE9C0001,
+               0x81C, 0xED9E0001,
+               0x81C, 0xECA00001,
+               0x81C, 0xEBA20001,
+               0x81C, 0xEAA40001,
+               0x81C, 0xE9A60001,
+               0x81C, 0xE8A80001,
+               0x81C, 0xE7AA0001,
+               0x81C, 0xE6AC0001,
+               0x81C, 0xE5AE0001,
+               0x81C, 0xE4B00001,
+               0x81C, 0xE3B20001,
+               0x81C, 0xA8B40001,
+               0x81C, 0xA7B60001,
+               0x81C, 0xA6B80001,
+               0x81C, 0xA5BA0001,
+               0x81C, 0xA4BC0001,
+               0x81C, 0xA3BE0001,
+               0x81C, 0xA2C00001,
+               0x81C, 0xA1C20001,
+               0x81C, 0x68C40001,
+               0x81C, 0x67C60001,
+               0x81C, 0x66C80001,
+               0x81C, 0x65CA0001,
+               0x81C, 0x64CC0001,
+               0x81C, 0x47CE0001,
+               0x81C, 0x46D00001,
+               0x81C, 0x45D20001,
+               0x81C, 0x44D40001,
+               0x81C, 0x43D60001,
+               0x81C, 0x42D80001,
+               0x81C, 0x08DA0001,
+               0x81C, 0x07DC0001,
+               0x81C, 0x06DE0001,
+               0x81C, 0x05E00001,
+               0x81C, 0x04E20001,
+               0x81C, 0x03E40001,
+               0x81C, 0x02E60001,
+               0x81C, 0x01E80001,
+               0x81C, 0x01EA0001,
+               0x81C, 0x01EC0001,
+               0x81C, 0x01EE0001,
+               0x81C, 0x01F00001,
+               0x81C, 0x01F20001,
+               0x81C, 0x01F40001,
+               0x81C, 0x01F60001,
+               0x81C, 0x01F80001,
+               0x81C, 0x01FA0001,
+               0x81C, 0x01FC0001,
+               0x81C, 0x01FE0001,
+       0xFF0F01C0, 0xCDEF,
+               0x81C, 0xFC800001,
+               0x81C, 0xFB820001,
+               0x81C, 0xFA840001,
+               0x81C, 0xF9860001,
+               0x81C, 0xF8880001,
+               0x81C, 0xF78A0001,
+               0x81C, 0xF68C0001,
+               0x81C, 0xF58E0001,
+               0x81C, 0xF4900001,
+               0x81C, 0xF3920001,
+               0x81C, 0xF2940001,
+               0x81C, 0xF1960001,
+               0x81C, 0xF0980001,
+               0x81C, 0xEF9A0001,
+               0x81C, 0xEE9C0001,
+               0x81C, 0xED9E0001,
+               0x81C, 0xECA00001,
+               0x81C, 0xEBA20001,
+               0x81C, 0xEAA40001,
+               0x81C, 0xE9A60001,
+               0x81C, 0xE8A80001,
+               0x81C, 0xE7AA0001,
+               0x81C, 0xE6AC0001,
+               0x81C, 0xE5AE0001,
+               0x81C, 0xE4B00001,
+               0x81C, 0xE3B20001,
+               0x81C, 0xA8B40001,
+               0x81C, 0xA7B60001,
+               0x81C, 0xA6B80001,
+               0x81C, 0xA5BA0001,
+               0x81C, 0xA4BC0001,
+               0x81C, 0xA3BE0001,
+               0x81C, 0xA2C00001,
+               0x81C, 0xA1C20001,
+               0x81C, 0x68C40001,
+               0x81C, 0x67C60001,
+               0x81C, 0x66C80001,
+               0x81C, 0x65CA0001,
+               0x81C, 0x64CC0001,
+               0x81C, 0x47CE0001,
+               0x81C, 0x46D00001,
+               0x81C, 0x45D20001,
+               0x81C, 0x44D40001,
+               0x81C, 0x43D60001,
+               0x81C, 0x42D80001,
+               0x81C, 0x08DA0001,
+               0x81C, 0x07DC0001,
+               0x81C, 0x06DE0001,
+               0x81C, 0x05E00001,
+               0x81C, 0x04E20001,
+               0x81C, 0x03E40001,
+               0x81C, 0x02E60001,
+               0x81C, 0x01E80001,
+               0x81C, 0x01EA0001,
+               0x81C, 0x01EC0001,
+               0x81C, 0x01EE0001,
+               0x81C, 0x01F00001,
+               0x81C, 0x01F20001,
+               0x81C, 0x01F40001,
+               0x81C, 0x01F60001,
+               0x81C, 0x01F80001,
+               0x81C, 0x01FA0001,
+               0x81C, 0x01FC0001,
+               0x81C, 0x01FE0001,
+       0xFF0F02C0, 0xCDEF,
+               0x81C, 0xFC800001,
+               0x81C, 0xFB820001,
+               0x81C, 0xFA840001,
+               0x81C, 0xF9860001,
+               0x81C, 0xF8880001,
+               0x81C, 0xF78A0001,
+               0x81C, 0xF68C0001,
+               0x81C, 0xF58E0001,
+               0x81C, 0xF4900001,
+               0x81C, 0xF3920001,
+               0x81C, 0xF2940001,
+               0x81C, 0xF1960001,
+               0x81C, 0xF0980001,
+               0x81C, 0xEF9A0001,
+               0x81C, 0xEE9C0001,
+               0x81C, 0xED9E0001,
+               0x81C, 0xECA00001,
+               0x81C, 0xEBA20001,
+               0x81C, 0xEAA40001,
+               0x81C, 0xE9A60001,
+               0x81C, 0xE8A80001,
+               0x81C, 0xE7AA0001,
+               0x81C, 0xE6AC0001,
+               0x81C, 0xE5AE0001,
+               0x81C, 0xE4B00001,
+               0x81C, 0xE3B20001,
+               0x81C, 0xA8B40001,
+               0x81C, 0xA7B60001,
+               0x81C, 0xA6B80001,
+               0x81C, 0xA5BA0001,
+               0x81C, 0xA4BC0001,
+               0x81C, 0xA3BE0001,
+               0x81C, 0xA2C00001,
+               0x81C, 0xA1C20001,
+               0x81C, 0x68C40001,
+               0x81C, 0x67C60001,
+               0x81C, 0x66C80001,
+               0x81C, 0x65CA0001,
+               0x81C, 0x64CC0001,
+               0x81C, 0x47CE0001,
+               0x81C, 0x46D00001,
+               0x81C, 0x45D20001,
+               0x81C, 0x44D40001,
+               0x81C, 0x43D60001,
+               0x81C, 0x42D80001,
+               0x81C, 0x08DA0001,
+               0x81C, 0x07DC0001,
+               0x81C, 0x06DE0001,
+               0x81C, 0x05E00001,
+               0x81C, 0x04E20001,
+               0x81C, 0x03E40001,
+               0x81C, 0x02E60001,
+               0x81C, 0x01E80001,
+               0x81C, 0x01EA0001,
+               0x81C, 0x01EC0001,
+               0x81C, 0x01EE0001,
+               0x81C, 0x01F00001,
+               0x81C, 0x01F20001,
+               0x81C, 0x01F40001,
+               0x81C, 0x01F60001,
+               0x81C, 0x01F80001,
+               0x81C, 0x01FA0001,
+               0x81C, 0x01FC0001,
+               0x81C, 0x01FE0001,
+       0xFF0F07D8, 0xCDEF,
+               0x81C, 0xFC800001,
+               0x81C, 0xFB820001,
+               0x81C, 0xFA840001,
+               0x81C, 0xF9860001,
+               0x81C, 0xF8880001,
+               0x81C, 0xF78A0001,
+               0x81C, 0xF68C0001,
+               0x81C, 0xF58E0001,
+               0x81C, 0xF4900001,
+               0x81C, 0xF3920001,
+               0x81C, 0xF2940001,
+               0x81C, 0xF1960001,
+               0x81C, 0xF0980001,
+               0x81C, 0xEF9A0001,
+               0x81C, 0xEE9C0001,
+               0x81C, 0xED9E0001,
+               0x81C, 0xECA00001,
+               0x81C, 0xEBA20001,
+               0x81C, 0xEAA40001,
+               0x81C, 0xE9A60001,
+               0x81C, 0xE8A80001,
+               0x81C, 0xE7AA0001,
+               0x81C, 0xE6AC0001,
+               0x81C, 0xE5AE0001,
+               0x81C, 0xE4B00001,
+               0x81C, 0xE3B20001,
+               0x81C, 0xA8B40001,
+               0x81C, 0xA7B60001,
+               0x81C, 0xA6B80001,
+               0x81C, 0xA5BA0001,
+               0x81C, 0xA4BC0001,
+               0x81C, 0xA3BE0001,
+               0x81C, 0xA2C00001,
+               0x81C, 0xA1C20001,
+               0x81C, 0x68C40001,
+               0x81C, 0x67C60001,
+               0x81C, 0x66C80001,
+               0x81C, 0x65CA0001,
+               0x81C, 0x64CC0001,
+               0x81C, 0x47CE0001,
+               0x81C, 0x46D00001,
+               0x81C, 0x45D20001,
+               0x81C, 0x44D40001,
+               0x81C, 0x43D60001,
+               0x81C, 0x42D80001,
+               0x81C, 0x08DA0001,
+               0x81C, 0x07DC0001,
+               0x81C, 0x06DE0001,
+               0x81C, 0x05E00001,
+               0x81C, 0x04E20001,
+               0x81C, 0x03E40001,
+               0x81C, 0x02E60001,
+               0x81C, 0x01E80001,
+               0x81C, 0x01EA0001,
+               0x81C, 0x01EC0001,
+               0x81C, 0x01EE0001,
+               0x81C, 0x01F00001,
+               0x81C, 0x01F20001,
+               0x81C, 0x01F40001,
+               0x81C, 0x01F60001,
+               0x81C, 0x01F80001,
+               0x81C, 0x01FA0001,
+               0x81C, 0x01FC0001,
+               0x81C, 0x01FE0001,
+       0xFF0F07D0, 0xCDEF,
+               0x81C, 0xFC800001,
+               0x81C, 0xFB820001,
+               0x81C, 0xFA840001,
+               0x81C, 0xF9860001,
+               0x81C, 0xF8880001,
+               0x81C, 0xF78A0001,
+               0x81C, 0xF68C0001,
+               0x81C, 0xF58E0001,
+               0x81C, 0xF4900001,
+               0x81C, 0xF3920001,
+               0x81C, 0xF2940001,
+               0x81C, 0xF1960001,
+               0x81C, 0xF0980001,
+               0x81C, 0xEF9A0001,
+               0x81C, 0xEE9C0001,
+               0x81C, 0xED9E0001,
+               0x81C, 0xECA00001,
+               0x81C, 0xEBA20001,
+               0x81C, 0xEAA40001,
+               0x81C, 0xE9A60001,
+               0x81C, 0xE8A80001,
+               0x81C, 0xE7AA0001,
+               0x81C, 0xE6AC0001,
+               0x81C, 0xE5AE0001,
+               0x81C, 0xE4B00001,
+               0x81C, 0xE3B20001,
+               0x81C, 0xA8B40001,
+               0x81C, 0xA7B60001,
+               0x81C, 0xA6B80001,
+               0x81C, 0xA5BA0001,
+               0x81C, 0xA4BC0001,
+               0x81C, 0xA3BE0001,
+               0x81C, 0xA2C00001,
+               0x81C, 0xA1C20001,
+               0x81C, 0x68C40001,
+               0x81C, 0x67C60001,
+               0x81C, 0x66C80001,
+               0x81C, 0x65CA0001,
+               0x81C, 0x64CC0001,
+               0x81C, 0x47CE0001,
+               0x81C, 0x46D00001,
+               0x81C, 0x45D20001,
+               0x81C, 0x44D40001,
+               0x81C, 0x43D60001,
+               0x81C, 0x42D80001,
+               0x81C, 0x08DA0001,
+               0x81C, 0x07DC0001,
+               0x81C, 0x06DE0001,
+               0x81C, 0x05E00001,
+               0x81C, 0x04E20001,
+               0x81C, 0x03E40001,
+               0x81C, 0x02E60001,
+               0x81C, 0x01E80001,
+               0x81C, 0x01EA0001,
+               0x81C, 0x01EC0001,
+               0x81C, 0x01EE0001,
+               0x81C, 0x01F00001,
+               0x81C, 0x01F20001,
+               0x81C, 0x01F40001,
+               0x81C, 0x01F60001,
+               0x81C, 0x01F80001,
+               0x81C, 0x01FA0001,
+               0x81C, 0x01FC0001,
+               0x81C, 0x01FE0001,
+       0xCDCDCDCD, 0xCDCD,
+               0x81C, 0xFF800001,
+               0x81C, 0xFF820001,
+               0x81C, 0xFF840001,
+               0x81C, 0xFE860001,
+               0x81C, 0xFD880001,
+               0x81C, 0xFC8A0001,
+               0x81C, 0xFB8C0001,
+               0x81C, 0xFA8E0001,
+               0x81C, 0xF9900001,
+               0x81C, 0xF8920001,
+               0x81C, 0xF7940001,
+               0x81C, 0xF6960001,
+               0x81C, 0xF5980001,
+               0x81C, 0xF49A0001,
+               0x81C, 0xF39C0001,
+               0x81C, 0xF29E0001,
+               0x81C, 0xF1A00001,
+               0x81C, 0xF0A20001,
+               0x81C, 0xEFA40001,
+               0x81C, 0xEEA60001,
+               0x81C, 0xEDA80001,
+               0x81C, 0xECAA0001,
+               0x81C, 0xEBAC0001,
+               0x81C, 0xEAAE0001,
+               0x81C, 0xE9B00001,
+               0x81C, 0xE8B20001,
+               0x81C, 0xE7B40001,
+               0x81C, 0xE6B60001,
+               0x81C, 0xE5B80001,
+               0x81C, 0xE4BA0001,
+               0x81C, 0xE3BC0001,
+               0x81C, 0xA8BE0001,
+               0x81C, 0xA7C00001,
+               0x81C, 0xA6C20001,
+               0x81C, 0xA5C40001,
+               0x81C, 0xA4C60001,
+               0x81C, 0xA3C80001,
+               0x81C, 0xA2CA0001,
+               0x81C, 0xA1CC0001,
+               0x81C, 0x68CE0001,
+               0x81C, 0x67D00001,
+               0x81C, 0x66D20001,
+               0x81C, 0x65D40001,
+               0x81C, 0x64D60001,
+               0x81C, 0x47D80001,
+               0x81C, 0x46DA0001,
+               0x81C, 0x45DC0001,
+               0x81C, 0x44DE0001,
+               0x81C, 0x43E00001,
+               0x81C, 0x42E20001,
+               0x81C, 0x08E40001,
+               0x81C, 0x07E60001,
+               0x81C, 0x06E80001,
+               0x81C, 0x05EA0001,
+               0x81C, 0x04EC0001,
+               0x81C, 0x03EE0001,
+               0x81C, 0x02F00001,
+               0x81C, 0x01F20001,
+               0x81C, 0x01F40001,
+               0x81C, 0x01F60001,
+               0x81C, 0x01F80001,
+               0x81C, 0x01FA0001,
+               0x81C, 0x01FC0001,
+               0x81C, 0x01FE0001,
+       0xFF0F0180, 0xDEAD,
+               0xC50, 0x00000022,
+               0xC50, 0x00000020,
+               0xE50, 0x00000022,
+               0xE50, 0x00000020,
+};
+
+u32 RTL8821AE_AGC_TAB_ARRAY[] = {
+               0x81C, 0xBF000001,
+               0x81C, 0xBF020001,
+               0x81C, 0xBF040001,
+               0x81C, 0xBF060001,
+               0x81C, 0xBE080001,
+               0x81C, 0xBD0A0001,
+               0x81C, 0xBC0C0001,
+               0x81C, 0xBA0E0001,
+               0x81C, 0xB9100001,
+               0x81C, 0xB8120001,
+               0x81C, 0xB7140001,
+               0x81C, 0xB6160001,
+               0x81C, 0xB5180001,
+               0x81C, 0xB41A0001,
+               0x81C, 0xB31C0001,
+               0x81C, 0xB21E0001,
+               0x81C, 0xB1200001,
+               0x81C, 0xB0220001,
+               0x81C, 0xAF240001,
+               0x81C, 0xAE260001,
+               0x81C, 0xAD280001,
+               0x81C, 0xAC2A0001,
+               0x81C, 0xAB2C0001,
+               0x81C, 0xAA2E0001,
+               0x81C, 0xA9300001,
+               0x81C, 0xA8320001,
+               0x81C, 0xA7340001,
+               0x81C, 0xA6360001,
+               0x81C, 0xA5380001,
+               0x81C, 0xA43A0001,
+               0x81C, 0xA33C0001,
+               0x81C, 0x673E0001,
+               0x81C, 0x66400001,
+               0x81C, 0x65420001,
+               0x81C, 0x64440001,
+               0x81C, 0x63460001,
+               0x81C, 0x62480001,
+               0x81C, 0x614A0001,
+               0x81C, 0x474C0001,
+               0x81C, 0x464E0001,
+               0x81C, 0x45500001,
+               0x81C, 0x44520001,
+               0x81C, 0x43540001,
+               0x81C, 0x42560001,
+               0x81C, 0x41580001,
+               0x81C, 0x285A0001,
+               0x81C, 0x275C0001,
+               0x81C, 0x265E0001,
+               0x81C, 0x25600001,
+               0x81C, 0x24620001,
+               0x81C, 0x0A640001,
+               0x81C, 0x09660001,
+               0x81C, 0x08680001,
+               0x81C, 0x076A0001,
+               0x81C, 0x066C0001,
+               0x81C, 0x056E0001,
+               0x81C, 0x04700001,
+               0x81C, 0x03720001,
+               0x81C, 0x02740001,
+               0x81C, 0x01760001,
+               0x81C, 0x01780001,
+               0x81C, 0x017A0001,
+               0x81C, 0x017C0001,
+               0x81C, 0x017E0001,
+       0xFF0F02C0, 0xABCD,
+               0x81C, 0xFB000101,
+               0x81C, 0xFA020101,
+               0x81C, 0xF9040101,
+               0x81C, 0xF8060101,
+               0x81C, 0xF7080101,
+               0x81C, 0xF60A0101,
+               0x81C, 0xF50C0101,
+               0x81C, 0xF40E0101,
+               0x81C, 0xF3100101,
+               0x81C, 0xF2120101,
+               0x81C, 0xF1140101,
+               0x81C, 0xF0160101,
+               0x81C, 0xEF180101,
+               0x81C, 0xEE1A0101,
+               0x81C, 0xED1C0101,
+               0x81C, 0xEC1E0101,
+               0x81C, 0xEB200101,
+               0x81C, 0xEA220101,
+               0x81C, 0xE9240101,
+               0x81C, 0xE8260101,
+               0x81C, 0xE7280101,
+               0x81C, 0xE62A0101,
+               0x81C, 0xE52C0101,
+               0x81C, 0xE42E0101,
+               0x81C, 0xE3300101,
+               0x81C, 0xA5320101,
+               0x81C, 0xA4340101,
+               0x81C, 0xA3360101,
+               0x81C, 0x87380101,
+               0x81C, 0x863A0101,
+               0x81C, 0x853C0101,
+               0x81C, 0x843E0101,
+               0x81C, 0x69400101,
+               0x81C, 0x68420101,
+               0x81C, 0x67440101,
+               0x81C, 0x66460101,
+               0x81C, 0x49480101,
+               0x81C, 0x484A0101,
+               0x81C, 0x474C0101,
+               0x81C, 0x2A4E0101,
+               0x81C, 0x29500101,
+               0x81C, 0x28520101,
+               0x81C, 0x27540101,
+               0x81C, 0x26560101,
+               0x81C, 0x25580101,
+               0x81C, 0x245A0101,
+               0x81C, 0x235C0101,
+               0x81C, 0x055E0101,
+               0x81C, 0x04600101,
+               0x81C, 0x03620101,
+               0x81C, 0x02640101,
+               0x81C, 0x01660101,
+               0x81C, 0x01680101,
+               0x81C, 0x016A0101,
+               0x81C, 0x016C0101,
+               0x81C, 0x016E0101,
+               0x81C, 0x01700101,
+               0x81C, 0x01720101,
+       0xCDCDCDCD, 0xCDCD,
+               0x81C, 0xFF000101,
+               0x81C, 0xFF020101,
+               0x81C, 0xFE040101,
+               0x81C, 0xFD060101,
+               0x81C, 0xFC080101,
+               0x81C, 0xFD0A0101,
+               0x81C, 0xFC0C0101,
+               0x81C, 0xFB0E0101,
+               0x81C, 0xFA100101,
+               0x81C, 0xF9120101,
+               0x81C, 0xF8140101,
+               0x81C, 0xF7160101,
+               0x81C, 0xF6180101,
+               0x81C, 0xF51A0101,
+               0x81C, 0xF41C0101,
+               0x81C, 0xF31E0101,
+               0x81C, 0xF2200101,
+               0x81C, 0xF1220101,
+               0x81C, 0xF0240101,
+               0x81C, 0xEF260101,
+               0x81C, 0xEE280101,
+               0x81C, 0xED2A0101,
+               0x81C, 0xEC2C0101,
+               0x81C, 0xEB2E0101,
+               0x81C, 0xEA300101,
+               0x81C, 0xE9320101,
+               0x81C, 0xE8340101,
+               0x81C, 0xE7360101,
+               0x81C, 0xE6380101,
+               0x81C, 0xE53A0101,
+               0x81C, 0xE43C0101,
+               0x81C, 0xE33E0101,
+               0x81C, 0xA5400101,
+               0x81C, 0xA4420101,
+               0x81C, 0xA3440101,
+               0x81C, 0x87460101,
+               0x81C, 0x86480101,
+               0x81C, 0x854A0101,
+               0x81C, 0x844C0101,
+               0x81C, 0x694E0101,
+               0x81C, 0x68500101,
+               0x81C, 0x67520101,
+               0x81C, 0x66540101,
+               0x81C, 0x49560101,
+               0x81C, 0x48580101,
+               0x81C, 0x475A0101,
+               0x81C, 0x2A5C0101,
+               0x81C, 0x295E0101,
+               0x81C, 0x28600101,
+               0x81C, 0x27620101,
+               0x81C, 0x26640101,
+               0x81C, 0x25660101,
+               0x81C, 0x24680101,
+               0x81C, 0x236A0101,
+               0x81C, 0x056C0101,
+               0x81C, 0x046E0101,
+               0x81C, 0x03700101,
+               0x81C, 0x02720101,
+       0xFF0F02C0, 0xDEAD,
+               0x81C, 0x01740101,
+               0x81C, 0x01760101,
+               0x81C, 0x01780101,
+               0x81C, 0x017A0101,
+               0x81C, 0x017C0101,
+               0x81C, 0x017E0101,
+               0xC50, 0x00000022,
+               0xC50, 0x00000020,
+
+};
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/table.h b/drivers/staging/rtl8821ae/rtl8821ae/table.h
new file mode 100644 (file)
index 0000000..b9d7b26
--- /dev/null
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ * Created on  2010/ 5/18,  1:41
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL8821AE_TABLE__H_
+#define __RTL8821AE_TABLE__H_
+
+#include <linux/types.h>
+#define  RTL8821AEPHY_REG_1TARRAYLEN   344
+extern u32 RTL8821AE_PHY_REG_ARRAY[];
+#define  RTL8812AEPHY_REG_1TARRAYLEN   490
+extern u32 RTL8812AE_PHY_REG_ARRAY[];
+#define RTL8821AEPHY_REG_ARRAY_PGLEN   90
+extern u32 RTL8821AE_PHY_REG_ARRAY_PG[];
+#define RTL8812AEPHY_REG_ARRAY_PGLEN   276
+extern u32 RTL8812AE_PHY_REG_ARRAY_PG[];
+//#define      RTL8723BE_RADIOA_1TARRAYLEN     206
+//extern u8 *RTL8821AE_TXPWR_LMT_ARRAY[];
+#define        RTL8812AE_RADIOA_1TARRAYLEN     1264
+extern u32 RTL8812AE_RADIOA_ARRAY[];
+#define        RTL8812AE_RADIOB_1TARRAYLEN     1240
+extern u32 RTL8812AE_RADIOB_ARRAY[];
+#define        RTL8821AE_RADIOA_1TARRAYLEN     1176
+extern u32 RTL8821AE_RADIOA_ARRAY[];
+#define RTL8821AEMAC_1T_ARRAYLEN               194
+extern u32 RTL8821AE_MAC_REG_ARRAY[];
+#define RTL8812AEMAC_1T_ARRAYLEN               214
+extern u32 RTL8812AE_MAC_REG_ARRAY[];
+#define RTL8821AEAGCTAB_1TARRAYLEN             382
+extern u32 RTL8821AE_AGC_TAB_ARRAY[];
+#define RTL8812AEAGCTAB_1TARRAYLEN             1312
+extern u32 RTL8812AE_AGC_TAB_ARRAY[];
+
+
+#endif
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/trx.c b/drivers/staging/rtl8821ae/rtl8821ae/trx.c
new file mode 100644 (file)
index 0000000..2c79787
--- /dev/null
@@ -0,0 +1,1050 @@
+/******************************************************************************
+ *
+ * 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 "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "../stats.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "trx.h"
+#include "led.h"
+#include "dm.h"
+#include "phy.h"
+u8 _rtl8821ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
+{
+       u16 fc = rtl_get_fc(skb);
+
+       if (unlikely(ieee80211_is_beacon(fc)))
+               return QSLT_BEACON;
+       if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
+               return QSLT_MGNT;
+
+       return skb->priority;
+}
+
+/* mac80211's rate_idx is like this:
+ *
+ * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
+ *
+ * B/G rate:
+ * (rx_status->flag & RX_FLAG_HT) = 0,
+ * DESC_RATE1M-->DESC_RATE54M ==> idx is 0-->11,
+ *
+ * N rate:
+ * (rx_status->flag & RX_FLAG_HT) = 1,
+ * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15
+ *
+ * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
+ * A rate:
+ * (rx_status->flag & RX_FLAG_HT) = 0,
+ * DESC_RATE6M-->DESC_RATE54M ==> idx is 0-->7,
+ *
+ * N rate:
+ * (rx_status->flag & RX_FLAG_HT) = 1,
+ * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15
+ */
+static int _rtl8821ae_rate_mapping(struct ieee80211_hw *hw,
+       bool isht, u8 desc_rate)
+{
+       int rate_idx;
+
+       if (false == isht) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+               if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
+#else
+               if (IEEE80211_BAND_2GHZ == hw->conf.channel->band) {
+#endif
+                       switch (desc_rate) {
+                       case DESC_RATE1M:
+                               rate_idx = 0;
+                               break;
+                       case DESC_RATE2M:
+                               rate_idx = 1;
+                               break;
+                       case DESC_RATE5_5M:
+                               rate_idx = 2;
+                               break;
+                       case DESC_RATE11M:
+                               rate_idx = 3;
+                               break;
+                       case DESC_RATE6M:
+                               rate_idx = 4;
+                               break;
+                       case DESC_RATE9M:
+                               rate_idx = 5;
+                               break;
+                       case DESC_RATE12M:
+                               rate_idx = 6;
+                               break;
+                       case DESC_RATE18M:
+                               rate_idx = 7;
+                               break;
+                       case DESC_RATE24M:
+                               rate_idx = 8;
+                               break;
+                       case DESC_RATE36M:
+                               rate_idx = 9;
+                               break;
+                       case DESC_RATE48M:
+                               rate_idx = 10;
+                               break;
+                       case DESC_RATE54M:
+                               rate_idx = 11;
+                               break;
+                       default:
+                               rate_idx = 0;
+                               break;
+                       }
+               } else {
+                       switch (desc_rate) {
+                       case DESC_RATE6M:
+                               rate_idx = 0;
+                               break;
+                       case DESC_RATE9M:
+                               rate_idx = 1;
+                               break;
+                       case DESC_RATE12M:
+                               rate_idx = 2;
+                               break;
+                       case DESC_RATE18M:
+                               rate_idx = 3;
+                               break;
+                       case DESC_RATE24M:
+                               rate_idx = 4;
+                               break;
+                       case DESC_RATE36M:
+                               rate_idx = 5;
+                               break;
+                       case DESC_RATE48M:
+                               rate_idx = 6;
+                               break;
+                       case DESC_RATE54M:
+                               rate_idx = 7;
+                               break;
+                       default:
+                               rate_idx = 0;
+                               break;
+                       }
+               }
+       } else {
+               switch(desc_rate) {
+               case DESC_RATEMCS0:
+                       rate_idx = 0;
+                       break;
+               case DESC_RATEMCS1:
+                       rate_idx = 1;
+                       break;
+               case DESC_RATEMCS2:
+                       rate_idx = 2;
+                       break;
+               case DESC_RATEMCS3:
+                       rate_idx = 3;
+                       break;
+               case DESC_RATEMCS4:
+                       rate_idx = 4;
+                       break;
+               case DESC_RATEMCS5:
+                       rate_idx = 5;
+                       break;
+               case DESC_RATEMCS6:
+                       rate_idx = 6;
+                       break;
+               case DESC_RATEMCS7:
+                       rate_idx = 7;
+                       break;
+               case DESC_RATEMCS8:
+                       rate_idx = 8;
+                       break;
+               case DESC_RATEMCS9:
+                       rate_idx = 9;
+                       break;
+               case DESC_RATEMCS10:
+                       rate_idx = 10;
+                       break;
+               case DESC_RATEMCS11:
+                       rate_idx = 11;
+                       break;
+               case DESC_RATEMCS12:
+                       rate_idx = 12;
+                       break;
+               case DESC_RATEMCS13:
+                       rate_idx = 13;
+                       break;
+               case DESC_RATEMCS14:
+                       rate_idx = 14;
+                       break;
+               case DESC_RATEMCS15:
+                       rate_idx = 15;
+                       break;
+               default:
+                       rate_idx = 0;
+                       break;
+               }
+       }
+       return rate_idx;
+}
+
+static void _rtl8821ae_query_rxphystatus(struct ieee80211_hw *hw,
+                       struct rtl_stats *pstatus, u8 *pdesc,
+                       struct rx_fwinfo_8821ae *p_drvinfo, bool bpacket_match_bssid,
+                       bool bpacket_toself, bool b_packet_beacon)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
+       struct phy_sts_cck_8821ae_t *cck_buf;
+       struct phy_status_rpt *p_phystRpt = (struct phy_status_rpt *)p_drvinfo;
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+       char rx_pwr_all = 0, rx_pwr[4];
+       u8 rf_rx_num = 0, evm, pwdb_all;
+       u8 i, max_spatial_stream;
+       u32 rssi, total_rssi = 0;
+       bool b_is_cck = pstatus->b_is_cck;
+       u8 lan_idx,vga_idx;
+
+       /* Record it for next packet processing */
+       pstatus->b_packet_matchbssid = bpacket_match_bssid;
+       pstatus->b_packet_toself = bpacket_toself;
+       pstatus->b_packet_beacon = b_packet_beacon;
+       pstatus->rx_mimo_signalquality[0] = -1;
+       pstatus->rx_mimo_signalquality[1] = -1;
+
+       if (b_is_cck) {
+               u8 cck_highpwr;
+               u8 cck_agc_rpt;
+               /* CCK Driver info Structure is not the same as OFDM packet. */
+               cck_buf = (struct phy_sts_cck_8821ae_t *)p_drvinfo;
+               cck_agc_rpt = cck_buf->cck_agc_rpt;
+
+               /* (1)Hardware does not provide RSSI for CCK */
+               /* (2)PWDB, Average PWDB cacluated by
+                * hardware (for rate adaptive) */
+               if (ppsc->rfpwr_state == ERFON)
+                       cck_highpwr = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2,
+                                                        BIT(9));
+               else
+                       cck_highpwr = false;
+
+               lan_idx = ((cck_agc_rpt & 0xE0) >> 5);
+               vga_idx = (cck_agc_rpt & 0x1f);
+               switch (lan_idx) {
+                       case 7:
+                               if(vga_idx <= 27)
+                                       rx_pwr_all = -100 + 2*(27-vga_idx); /*VGA_idx = 27~2*/
+                               else
+                                       rx_pwr_all = -100;
+                               break;
+                       case 6:
+                               rx_pwr_all = -48 + 2*(2-vga_idx); /*VGA_idx = 2~0*/
+                               break;
+                       case 5:
+                               rx_pwr_all = -42 + 2*(7-vga_idx); /*VGA_idx = 7~5*/
+                               break;
+                       case 4:
+                               rx_pwr_all = -36 + 2*(7-vga_idx); /*VGA_idx = 7~4*/
+                               break;
+                       case 3:
+                               rx_pwr_all = -24 + 2*(7-vga_idx); /*VGA_idx = 7~0*/
+                               break;
+                       case 2:
+                               if(cck_highpwr)
+                                       rx_pwr_all = -12 + 2*(5-vga_idx); /*VGA_idx = 5~0*/
+                               else
+                                       rx_pwr_all = -6+ 2*(5-vga_idx);
+                               break;
+                       case 1:
+                               rx_pwr_all = 8-2*vga_idx;
+                               break;
+                       case 0:
+                               rx_pwr_all = 14-2*vga_idx;
+                               break;
+                       default:
+                               break;
+               }
+               rx_pwr_all += 6;
+               pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
+               /* CCK gain is smaller than OFDM/MCS gain,  */
+               /* so we add gain diff by experiences,
+                * the val is 6 */
+               pwdb_all += 6;
+               if(pwdb_all > 100)
+                       pwdb_all = 100;
+               /* modify the offset to make the same
+                * gain index with OFDM. */
+               if(pwdb_all > 34 && pwdb_all <= 42)
+                       pwdb_all -= 2;
+               else if(pwdb_all > 26 && pwdb_all <= 34)
+                       pwdb_all -= 6;
+               else if(pwdb_all > 14 && pwdb_all <= 26)
+                       pwdb_all -= 8;
+               else if(pwdb_all > 4 && pwdb_all <= 14)
+                       pwdb_all -= 4;
+               if (cck_highpwr == false){
+                       if (pwdb_all >= 80)
+                               pwdb_all =((pwdb_all-80)<<1)+((pwdb_all-80)>>1)+80;
+                       else if((pwdb_all <= 78) && (pwdb_all >= 20))
+                               pwdb_all += 3;
+                       if(pwdb_all>100)
+                               pwdb_all = 100;
+               }
+
+               pstatus->rx_pwdb_all = pwdb_all;
+               pstatus->recvsignalpower = rx_pwr_all;
+
+               /* (3) Get Signal Quality (EVM) */
+               if (bpacket_match_bssid) {
+                       u8 sq;
+
+                       if (pstatus->rx_pwdb_all > 40)
+                               sq = 100;
+                       else {
+                               sq = cck_buf->sq_rpt;
+                               if (sq > 64)
+                                       sq = 0;
+                               else if (sq < 20)
+                                       sq = 100;
+                               else
+                                       sq = ((64 - sq) * 100) / 44;
+                       }
+
+                       pstatus->signalquality = sq;
+                       pstatus->rx_mimo_signalquality[0] = sq;
+                       pstatus->rx_mimo_signalquality[1] = -1;
+               }
+       } else {
+               rtlpriv->dm.brfpath_rxenable[0] =
+                   rtlpriv->dm.brfpath_rxenable[1] = true;
+
+               /* (1)Get RSSI for HT rate */
+               for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
+
+                       /* we will judge RF RX path now. */
+                       if (rtlpriv->dm.brfpath_rxenable[i])
+                               rf_rx_num++;
+
+                       rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
+
+                       /* Translate DBM to percentage. */
+                       rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
+                       total_rssi += rssi;
+
+                       /* Get Rx snr value in DB */
+                       rtlpriv->stats.rx_snr_db[i] = (long)(p_drvinfo->rxsnr[i] / 2);
+
+                       /* Record Signal Strength for next packet */
+                       if (bpacket_match_bssid)
+                               pstatus->rx_mimo_signalstrength[i] = (u8) rssi;
+               }
+
+               /* (2)PWDB, Average PWDB cacluated by
+                * hardware (for rate adaptive) */
+               rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
+
+               pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
+               pstatus->rx_pwdb_all = pwdb_all;
+               pstatus->rxpower = rx_pwr_all;
+               pstatus->recvsignalpower = rx_pwr_all;
+
+               /* (3)EVM of HT rate */
+               if (pstatus->b_is_ht && pstatus->rate >= DESC_RATEMCS8 &&
+                   pstatus->rate <= DESC_RATEMCS15)
+                       max_spatial_stream = 2;
+               else
+                       max_spatial_stream = 1;
+
+               for (i = 0; i < max_spatial_stream; i++) {
+                       evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
+
+                       if (bpacket_match_bssid) {
+                               /* Fill value in RFD, Get the first
+                                * spatial stream only */
+                               if (i == 0)
+                                       pstatus->signalquality = (u8) (evm & 0xff);
+                               pstatus->rx_mimo_signalquality[i] = (u8) (evm & 0xff);
+                       }
+               }
+       }
+
+       /* UI BSS List signal strength(in percentage),
+        * make it good looking, from 0~100. */
+       if (b_is_cck)
+               pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
+                       pwdb_all));
+       else if (rf_rx_num != 0)
+               pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
+                       total_rssi /= rf_rx_num));
+       /*HW antenna diversity*/
+       rtldm->fat_table.antsel_rx_keep_0 = p_phystRpt->ant_sel;
+       rtldm->fat_table.antsel_rx_keep_1 = p_phystRpt->ant_sel_b;
+       rtldm->fat_table.antsel_rx_keep_2 = p_phystRpt->antsel_rx_keep_2;
+
+}
+#if 0
+static void _rtl8821ae_smart_antenna(struct ieee80211_hw *hw,
+       struct rtl_stats *pstatus)
+{
+       struct rtl_dm *rtldm= rtl_dm(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse =rtl_efuse(rtl_priv(hw));
+       u8 antsel_tr_mux;
+       struct fast_ant_trainning *pfat_table = &(rtldm->fat_table);
+
+       if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV) {
+               if (pfat_table->fat_state == FAT_TRAINING_STATE) {
+                       if (pstatus->b_packet_toself) {
+                               antsel_tr_mux = (pfat_table->antsel_rx_keep_2 << 2) |
+                                       (pfat_table->antsel_rx_keep_1 << 1) | pfat_table->antsel_rx_keep_0;
+                               pfat_table->ant_sum_rssi[antsel_tr_mux] += pstatus->rx_pwdb_all;
+                               pfat_table->ant_rssi_cnt[antsel_tr_mux]++;
+                       }
+               }
+       } else if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
+       (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)) {
+               if (pstatus->b_packet_toself || pstatus->b_packet_matchbssid) {
+                       antsel_tr_mux = (pfat_table->antsel_rx_keep_2 << 2) |
+                                       (pfat_table->antsel_rx_keep_1 << 1) | pfat_table->antsel_rx_keep_0;
+                       rtl8821ae_dm_ant_sel_statistics(hw, antsel_tr_mux, 0, pstatus->rx_pwdb_all);
+               }
+
+       }
+}
+#endif
+static void _rtl8821ae_translate_rx_signal_stuff(struct ieee80211_hw *hw,
+               struct sk_buff *skb, struct rtl_stats *pstatus,
+               u8 *pdesc, struct rx_fwinfo_8821ae *p_drvinfo)
+{
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct ieee80211_hdr *hdr;
+       u8 *tmp_buf;
+       u8 *praddr;
+       u8 *psaddr;
+       u16 fc, type;
+       bool b_packet_matchbssid, b_packet_toself, b_packet_beacon;
+
+       tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
+
+       hdr = (struct ieee80211_hdr *)tmp_buf;
+       fc = le16_to_cpu(hdr->frame_control);
+       type = WLAN_FC_GET_TYPE(fc);
+       praddr = hdr->addr1;
+       psaddr = ieee80211_get_SA(hdr);
+       memcpy(pstatus->psaddr, psaddr, ETH_ALEN);
+
+       b_packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
+            (!compare_ether_addr(mac->bssid, (fc & IEEE80211_FCTL_TODS) ?
+                                 hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
+                                 hdr->addr2 : hdr->addr3)) && (!pstatus->b_hwerror) &&
+                                 (!pstatus->b_crc) && (!pstatus->b_icv));
+
+       b_packet_toself = b_packet_matchbssid &&
+           (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+
+       if (ieee80211_is_beacon(fc))
+               b_packet_beacon = true;
+       else
+               b_packet_beacon = false;
+
+       if (b_packet_beacon && b_packet_matchbssid)
+               rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++;
+
+       _rtl8821ae_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo,
+                                  b_packet_matchbssid, b_packet_toself,
+                                  b_packet_beacon);
+       /*_rtl8821ae_smart_antenna(hw, pstatus); */
+       rtl_process_phyinfo(hw, tmp_buf, pstatus);
+}
+
+static void _rtl8821ae_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
+                                     u8 *virtualaddress)
+{
+       u32 dwtmp = 0;
+       memset(virtualaddress, 0, 8);
+
+       SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
+       if (ptcb_desc->empkt_num == 1)
+               dwtmp = ptcb_desc->empkt_len[0];
+       else {
+               dwtmp = ptcb_desc->empkt_len[0];
+               dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+               dwtmp += ptcb_desc->empkt_len[1];
+       }
+       SET_EARLYMODE_LEN0(virtualaddress, dwtmp);
+
+       if (ptcb_desc->empkt_num <= 3)
+               dwtmp = ptcb_desc->empkt_len[2];
+       else {
+               dwtmp = ptcb_desc->empkt_len[2];
+               dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+               dwtmp += ptcb_desc->empkt_len[3];
+       }
+       SET_EARLYMODE_LEN1(virtualaddress, dwtmp);
+       if (ptcb_desc->empkt_num <= 5)
+               dwtmp = ptcb_desc->empkt_len[4];
+       else {
+               dwtmp = ptcb_desc->empkt_len[4];
+               dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+               dwtmp += ptcb_desc->empkt_len[5];
+       }
+       SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF);
+       SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4);
+       if (ptcb_desc->empkt_num <= 7)
+               dwtmp = ptcb_desc->empkt_len[6];
+       else {
+               dwtmp = ptcb_desc->empkt_len[6];
+               dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+               dwtmp += ptcb_desc->empkt_len[7];
+       }
+       SET_EARLYMODE_LEN3(virtualaddress, dwtmp);
+       if (ptcb_desc->empkt_num <= 9)
+               dwtmp = ptcb_desc->empkt_len[8];
+       else {
+               dwtmp = ptcb_desc->empkt_len[8];
+               dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
+               dwtmp += ptcb_desc->empkt_len[9];
+       }
+       SET_EARLYMODE_LEN4(virtualaddress, dwtmp);
+}
+
+bool rtl8821ae_rx_query_desc(struct ieee80211_hw *hw,
+                          struct rtl_stats *status,
+                          struct ieee80211_rx_status *rx_status,
+                          u8 *pdesc, struct sk_buff *skb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rx_fwinfo_8821ae *p_drvinfo;
+       struct ieee80211_hdr *hdr;
+
+       u32 phystatus = GET_RX_DESC_PHYST(pdesc);
+
+       status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
+       status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
+           RX_DRV_INFO_SIZE_UNIT;
+       status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
+       status->b_icv = (u16) GET_RX_DESC_ICV(pdesc);
+       status->b_crc = (u16) GET_RX_DESC_CRC32(pdesc);
+       status->b_hwerror = (status->b_crc | status->b_icv);
+       status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
+       status->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
+       status->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
+       status->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
+       status->b_isfirst_ampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
+       status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
+       status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
+       status->macid = GET_RX_DESC_MACID(pdesc);
+       status->b_is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
+
+       status->b_is_cck = RX_HAL_IS_CCK_RATE(status->rate);
+
+       if (GET_RX_STATUS_DESC_RPT_SEL(pdesc))
+               status->packet_report_type = C2H_PACKET;
+       else
+               status->packet_report_type = NORMAL_RX;
+
+       if (GET_RX_STATUS_DESC_PATTERN_MATCH(pdesc))
+               status->wake_match = BIT(2);
+       else if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
+               status->wake_match = BIT(1);
+       else if (GET_RX_STATUS_DESC_UNICAST_MATCH(pdesc))
+               status->wake_match = BIT(0);
+       else
+               status->wake_match = 0;
+
+       if (status->wake_match)
+               RT_TRACE(COMP_RXDESC,DBG_LOUD,
+               ("GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n",status->wake_match ));
+#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
+
+       hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size
+                       + status->rx_bufshift);
+
+       if (status->b_crc)
+               rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+       if (status->rx_is40Mhzpacket)
+               rx_status->flag |= RX_FLAG_40MHZ;
+
+       if (status->b_is_ht)
+               rx_status->flag |= RX_FLAG_HT;
+
+       rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+
+       /* hw will set status->decrypted true, if it finds the
+        * frame is open data frame or mgmt frame. */
+       /* So hw will not decryption robust managment frame
+        * for IEEE80211w but still set status->decrypted
+        * true, so here we should set it back to undecrypted
+        * for IEEE80211w frame, and mac80211 sw will help
+        * to decrypt it */
+       if (status->decrypted) {
+               if (!hdr) {
+                       WARN_ON_ONCE(true);
+                       pr_err("decrypted is true but hdr NULL, from skb %p\n",
+                               rtl_get_hdr(skb));
+                               return false;
+               }
+
+               if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
+                       (ieee80211_has_protected(hdr->frame_control)))
+                       rx_status->flag &= ~RX_FLAG_DECRYPTED;
+               else
+                       rx_status->flag |= RX_FLAG_DECRYPTED;
+       }
+
+       /* rate_idx: index of data rate into band's
+        * supported rates or MCS index if HT rates
+        * are use (RX_FLAG_HT)*/
+       /* Notice: this is diff with windows define */
+       rx_status->rate_idx = _rtl8821ae_rate_mapping(hw,
+                               status->b_is_ht, status->rate);
+
+       rx_status->mactime = status->timestamp_low;
+       if (phystatus == true) {
+               p_drvinfo = (struct rx_fwinfo_8821ae *)(skb->data +
+                                                    status->rx_bufshift);
+
+               _rtl8821ae_translate_rx_signal_stuff(hw,
+                                                  skb, status, pdesc,
+                                                  p_drvinfo);
+       }
+
+       /*rx_status->qual = status->signal; */
+       rx_status->signal = status->recvsignalpower + 10;
+       /*rx_status->noise = -status->noise; */
+       if (status->packet_report_type == TX_REPORT2){
+               status->macid_valid_entry[0] = GET_RX_RPT2_DESC_MACID_VALID_1(pdesc);
+               status->macid_valid_entry[1] = GET_RX_RPT2_DESC_MACID_VALID_2(pdesc);
+       }
+       return true;
+}
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw,
+                         struct ieee80211_hdr *hdr, u8 *pdesc_tx, u8 *txbd,
+                         struct ieee80211_tx_info *info, struct sk_buff *skb,
+                         u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
+#else
+/*<delete in kernel end>*/
+void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw,
+                         struct ieee80211_hdr *hdr, u8 *pdesc_tx, u8 *txbd,
+                         struct ieee80211_tx_info *info,
+                         struct ieee80211_sta *sta,
+                         struct sk_buff *skb,
+                         u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+       struct ieee80211_sta *sta = info->control.sta;
+#endif
+/*<delete in kernel end>*/
+       u8 *pdesc = (u8 *) pdesc_tx;
+       u16 seq_number;
+       u16 fc = le16_to_cpu(hdr->frame_control);
+       unsigned int buf_len = 0;
+       unsigned int skb_len = skb->len;
+       u8 fw_qsel = _rtl8821ae_map_hwqueue_to_fwqueue(skb, hw_queue);
+       bool b_firstseg = ((hdr->seq_ctrl &
+                           cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
+       bool b_lastseg = ((hdr->frame_control &
+                          cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
+       dma_addr_t mapping;
+       u8 bw_40 = 0;
+       u8 short_gi = 0;
+
+       if (mac->opmode == NL80211_IFTYPE_STATION) {
+               bw_40 = mac->bw_40;
+       } else if (mac->opmode == NL80211_IFTYPE_AP ||
+               mac->opmode == NL80211_IFTYPE_ADHOC) {
+               if (sta)
+                       bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+       }
+       seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
+       rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
+       /* reserve 8 byte for AMPDU early mode */
+       if (rtlhal->b_earlymode_enable) {
+               skb_push(skb, EM_HDR_LEN);
+               memset(skb->data, 0, EM_HDR_LEN);
+       }
+       buf_len = skb->len;
+       mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
+                                PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(COMP_SEND, DBG_TRACE,
+                        ("DMA mapping error"));
+               return;
+       }
+       CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8821ae));
+       if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
+               b_firstseg = true;
+               b_lastseg = true;
+       }
+       if (b_firstseg) {
+               if (rtlhal->b_earlymode_enable) {
+                       SET_TX_DESC_PKT_OFFSET(pdesc, 1);
+                       SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN + EM_HDR_LEN);
+                       if (ptcb_desc->empkt_num) {
+                               RT_TRACE(COMP_SEND, DBG_TRACE,
+                                        ("Insert 8 byte.pTcb->EMPktNum:%d\n",
+                                         ptcb_desc->empkt_num));
+                               _rtl8821ae_insert_emcontent(ptcb_desc, (u8 *)(skb->data));
+                       }
+               } else {
+                       SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
+               }
+
+               /* ptcb_desc->use_driver_rate = true; */
+               SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
+               if (ptcb_desc->hw_rate > DESC_RATEMCS0) {
+                       short_gi = (ptcb_desc->use_shortgi) ? 1 : 0;
+               } else {
+                       short_gi = (ptcb_desc->use_shortpreamble) ? 1 :0;
+               }
+               SET_TX_DESC_DATA_SHORTGI(pdesc, short_gi);
+
+               if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+                       SET_TX_DESC_AGG_ENABLE(pdesc, 1);
+                       SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
+               }
+               SET_TX_DESC_SEQ(pdesc, seq_number);
+               SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->b_rts_enable &&
+                                               !ptcb_desc->b_cts_enable) ? 1 : 0));
+               SET_TX_DESC_HW_RTS_ENABLE(pdesc,0);
+               SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->b_cts_enable) ? 1 : 0));
+       /*      SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->b_rts_stbc) ? 1 : 0));*/
+
+               SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
+       /*      SET_TX_DESC_RTS_BW(pdesc, 0);*/
+               SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
+               SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= DESC_RATE54M) ?
+                       (ptcb_desc->b_rts_use_shortpreamble ? 1 : 0) :
+                       (ptcb_desc->b_rts_use_shortgi ? 1 : 0)));
+
+               if(ptcb_desc->btx_enable_sw_calc_duration)
+                       SET_TX_DESC_NAV_USE_HDR(pdesc, 1);
+
+               if (bw_40) {
+                       if (ptcb_desc->b_packet_bw) {
+                               SET_TX_DESC_DATA_BW(pdesc, 1);
+                               SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
+                       } else {
+                               SET_TX_DESC_DATA_BW(pdesc, 0);
+                               SET_TX_DESC_TX_SUB_CARRIER(pdesc, mac->cur_40_prime_sc);
+                       }
+               } else {
+                       SET_TX_DESC_DATA_BW(pdesc, 0);
+                       SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
+               }
+
+               SET_TX_DESC_LINIP(pdesc, 0);
+               SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
+               if (sta) {
+                       u8 ampdu_density = sta->ht_cap.ampdu_density;
+                       SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
+               }
+               if (info->control.hw_key) {
+                       struct ieee80211_key_conf *keyconf = info->control.hw_key;
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+/*<delete in kernel end>*/
+                       switch (keyconf->cipher) {
+                       case WLAN_CIPHER_SUITE_WEP40:
+                       case WLAN_CIPHER_SUITE_WEP104:
+                       case WLAN_CIPHER_SUITE_TKIP:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
+                               break;
+                       case WLAN_CIPHER_SUITE_CCMP:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
+                               break;
+                       default:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
+                               break;
+
+                       }
+/*<delete in kernel start>*/
+#else
+                       switch (keyconf->alg) {
+                       case ALG_WEP:
+                       case ALG_TKIP:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
+                               break;
+                       case ALG_CCMP:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
+                               break;
+                       default:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
+                               break;
+
+                       }
+#endif
+/*<delete in kernel end>*/
+               }
+
+               SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
+               SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
+               SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
+               SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ? 1 : 0);
+               SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
+
+#if 0
+               SET_TX_DESC_USE_RATE(pdesc, 1);
+               SET_TX_DESC_TX_RATE(pdesc, 0x04);
+
+               SET_TX_DESC_RETRY_LIMIT_ENABLE(pdesc, 1);
+               SET_TX_DESC_DATA_RETRY_LIMIT(pdesc, 0x3f);
+#endif
+
+               /*SET_TX_DESC_PWR_STATUS(pdesc, pwr_status);*/
+               /* Set TxRate and RTSRate in TxDesc  */
+               /* This prevent Tx initial rate of new-coming packets */
+               /* from being overwritten by retried  packet rate.*/
+               if (!ptcb_desc->use_driver_rate) {
+                       /*SET_TX_DESC_RTS_RATE(pdesc, 0x08); */
+                       /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */
+               }
+               if (ieee80211_is_data_qos(fc)) {
+                       if (mac->rdg_en) {
+                               RT_TRACE(COMP_SEND, DBG_TRACE,
+                                       ("Enable RDG function.\n"));
+                               SET_TX_DESC_RDG_ENABLE(pdesc, 1);
+                               SET_TX_DESC_HTC(pdesc, 1);
+                       }
+               }
+       }
+
+       SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0));
+       SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0));
+       SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
+       SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+       //if (rtlpriv->dm.b_useramask) {
+       if(1){
+               SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
+               SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
+       } else {
+               SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
+               SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
+       }
+/*     if (ieee80211_is_data_qos(fc))
+               SET_TX_DESC_QOS(pdesc, 1);
+*/
+       if (!ieee80211_is_data_qos(fc))  {
+               SET_TX_DESC_HWSEQ_EN(pdesc, 1);
+               SET_TX_DESC_HWSEQ_SEL(pdesc, 0);
+       }
+       SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1));
+       if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
+           is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
+               SET_TX_DESC_BMC(pdesc, 1);
+       }
+
+       rtl8821ae_dm_set_tx_ant_by_tx_info(hw,pdesc,ptcb_desc->mac_id);
+       RT_TRACE(COMP_SEND, DBG_TRACE, ("\n"));
+}
+
+void rtl8821ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
+                            u8 *pdesc, bool b_firstseg,
+                            bool b_lastseg, struct sk_buff *skb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u8 fw_queue = QSLT_BEACON;
+
+       dma_addr_t mapping = pci_map_single(rtlpci->pdev,
+                                           skb->data, skb->len,
+                                           PCI_DMA_TODEVICE);
+
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(COMP_SEND, DBG_TRACE,
+                        ("DMA mapping error"));
+               return;
+       }
+       CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
+
+       SET_TX_DESC_FIRST_SEG(pdesc, 1);
+       SET_TX_DESC_LAST_SEG(pdesc, 1);
+
+       SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
+
+       SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
+
+       SET_TX_DESC_USE_RATE(pdesc, 1);
+       SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
+       SET_TX_DESC_DISABLE_FB(pdesc, 1);
+
+       SET_TX_DESC_DATA_BW(pdesc, 0);
+
+       SET_TX_DESC_HWSEQ_EN(pdesc, 1);
+
+       SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
+/*
+       if(IsCtrlNDPA(VirtualAddress) || IsMgntNDPA(VirtualAddress))
+       {
+               SET_TX_DESC_DATA_RETRY_LIMIT_8812(pDesc, 5);
+               SET_TX_DESC_RETRY_LIMIT_ENABLE_8812(pDesc, 1);
+
+               if(IsMgntNDPA(VirtualAddress))
+               {
+                       SET_TX_DESC_NDPA_8812(pDesc, 1);
+                       SET_TX_DESC_RTS_SC_8812(pDesc, SCMapping_8812(Adapter, pTcb));
+               }
+               else
+               {
+                       SET_TX_DESC_NDPA_8812(pDesc, 2);
+                       SET_TX_DESC_RTS_SC_8812(pDesc, SCMapping_8812(Adapter, pTcb));
+               }
+       }*/
+
+       SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
+
+       SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+       SET_TX_DESC_MACID(pdesc, 0);
+
+       SET_TX_DESC_OWN(pdesc, 1);
+
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+                     "H2C Tx Cmd Content\n",
+                     pdesc, TX_DESC_SIZE);
+}
+
+void rtl8821ae_set_desc(struct ieee80211_hw * hw, u8 *pdesc, bool istx, u8 desc_name, u8 *val)
+{
+       if (istx == true) {
+               switch (desc_name) {
+               case HW_DESC_OWN:
+                       SET_TX_DESC_OWN(pdesc, 1);
+                       break;
+               case HW_DESC_TX_NEXTDESC_ADDR:
+                       SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
+                       break;
+               default:
+                       RT_ASSERT(false, ("ERR txdesc :%d"
+                                         " not process\n", desc_name));
+                       break;
+               }
+       } else {
+               switch (desc_name) {
+               case HW_DESC_RXOWN:
+                       SET_RX_DESC_OWN(pdesc, 1);
+                       break;
+               case HW_DESC_RXBUFF_ADDR:
+                       SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
+                       break;
+               case HW_DESC_RXPKT_LEN:
+                       SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
+                       break;
+               case HW_DESC_RXERO:
+                       SET_RX_DESC_EOR(pdesc, 1);
+                       break;
+               default:
+                       RT_ASSERT(false, ("ERR rxdesc :%d "
+                                         "not process\n", desc_name));
+                       break;
+               }
+       }
+}
+
+u32 rtl8821ae_get_desc(u8 *pdesc, bool istx, u8 desc_name)
+{
+       u32 ret = 0;
+
+       if (istx == true) {
+               switch (desc_name) {
+               case HW_DESC_OWN:
+                       ret = GET_TX_DESC_OWN(pdesc);
+                       break;
+               case HW_DESC_TXBUFF_ADDR:
+                       ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
+                       break;
+               default:
+                       RT_ASSERT(false, ("ERR txdesc :%d "
+                                         "not process\n", desc_name));
+                       break;
+               }
+       } else {
+               switch (desc_name) {
+               case HW_DESC_OWN:
+                       ret = GET_RX_DESC_OWN(pdesc);
+                       break;
+               case HW_DESC_RXPKT_LEN:
+                       ret = GET_RX_DESC_PKT_LEN(pdesc);
+                       break;
+               default:
+                       RT_ASSERT(false, ("ERR rxdesc :%d "
+                                         "not process\n", desc_name));
+                       break;
+               }
+       }
+       return ret;
+}
+
+bool rtl8821ae_is_tx_desc_closed(struct ieee80211_hw *hw,
+                                u8 hw_queue, u16 index)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+       u8 *entry = (u8 *)(&ring->desc[ring->idx]);
+       u8 own = (u8) rtl8821ae_get_desc(entry, true, HW_DESC_OWN);
+
+       /*
+        *beacon packet will only use the first
+        *descriptor defautly,and the own may not
+        *be cleared by the hardware
+        */
+       if (own)
+               return false;
+       else
+               return true;
+}
+
+
+void rtl8821ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (hw_queue == BEACON_QUEUE) {
+               rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
+       } else {
+               rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
+                              BIT(0) << (hw_queue));
+       }
+}
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/trx.h b/drivers/staging/rtl8821ae/rtl8821ae/trx.h
new file mode 100644 (file)
index 0000000..da93e5c
--- /dev/null
@@ -0,0 +1,641 @@
+/******************************************************************************
+ *
+ * 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 __RTL8821AE_TRX_H__
+#define __RTL8821AE_TRX_H__
+
+#define TX_DESC_SIZE                                   40
+#define TX_DESC_AGGR_SUBFRAME_SIZE             32
+
+#define RX_DESC_SIZE                                   32
+#define RX_DRV_INFO_SIZE_UNIT                  8
+
+#define        TX_DESC_NEXT_DESC_OFFSET                40
+#define USB_HWDESC_HEADER_LEN                  40
+#define CRCLENGTH                                              4
+
+#define SET_TX_DESC_PKT_SIZE(__pdesc, __val)           \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
+#define SET_TX_DESC_OFFSET(__pdesc, __val)                     \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
+#define SET_TX_DESC_BMC(__pdesc, __val)                        \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
+#define SET_TX_DESC_HTC(__pdesc, __val)                        \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
+#define SET_TX_DESC_LAST_SEG(__pdesc, __val)           \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
+#define SET_TX_DESC_FIRST_SEG(__pdesc, __val)          \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
+#define SET_TX_DESC_LINIP(__pdesc, __val)                      \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
+#define SET_TX_DESC_NO_ACM(__pdesc, __val)                     \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
+#define SET_TX_DESC_GF(__pdesc, __val)                                 \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
+#define SET_TX_DESC_OWN(__pdesc, __val)                        \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
+
+#define GET_TX_DESC_PKT_SIZE(__pdesc)                          \
+       LE_BITS_TO_4BYTE(__pdesc, 0, 16)
+#define GET_TX_DESC_OFFSET(__pdesc)                                    \
+       LE_BITS_TO_4BYTE(__pdesc, 16, 8)
+#define GET_TX_DESC_BMC(__pdesc)                                       \
+       LE_BITS_TO_4BYTE(__pdesc, 24, 1)
+#define GET_TX_DESC_HTC(__pdesc)                                       \
+       LE_BITS_TO_4BYTE(__pdesc, 25, 1)
+#define GET_TX_DESC_LAST_SEG(__pdesc)                          \
+       LE_BITS_TO_4BYTE(__pdesc, 26, 1)
+#define GET_TX_DESC_FIRST_SEG(__pdesc)                                 \
+       LE_BITS_TO_4BYTE(__pdesc, 27, 1)
+#define GET_TX_DESC_LINIP(__pdesc)                                     \
+       LE_BITS_TO_4BYTE(__pdesc, 28, 1)
+#define GET_TX_DESC_NO_ACM(__pdesc)                                    \
+       LE_BITS_TO_4BYTE(__pdesc, 29, 1)
+#define GET_TX_DESC_GF(__pdesc)                                                \
+       LE_BITS_TO_4BYTE(__pdesc, 30, 1)
+#define GET_TX_DESC_OWN(__pdesc)                                       \
+       LE_BITS_TO_4BYTE(__pdesc, 31, 1)
+
+#define SET_TX_DESC_MACID(__pdesc, __val)                      \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 7, __val)
+#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val)          \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
+#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val)        \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
+#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val)       \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
+#define SET_TX_DESC_PIFS(__pdesc, __val)                       \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
+#define SET_TX_DESC_RATE_ID(__pdesc, __val)            \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 5, __val)
+#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val)                 \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
+#define SET_TX_DESC_SEC_TYPE(__pdesc, __val)           \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
+#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val)                 \
+       SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 5, __val)
+
+
+#define SET_TX_DESC_PAID(__pdesc, __val)                       \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 9, __val)
+#define SET_TX_DESC_CCA_RTS(__pdesc, __val)            \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 10, 2, __val)
+#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 12, 1, __val)
+#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 13, 1, __val)
+#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val)                 \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
+#define SET_TX_DESC_AGG_BREAK(__pdesc, __val)          \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 16, 1, __val)
+#define SET_TX_DESC_MORE_FRAG(__pdesc, __val)          \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
+#define SET_TX_DESC_RAW(__pdesc, __val)                        \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
+#define SET_TX_DESC_SPE_RPT(__pdesc, __val)                    \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
+#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val)      \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
+#define SET_TX_DESC_BT_INT(__pdesc, __val)     \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 23, 1, __val)
+#define SET_TX_DESC_GID(__pdesc, __val)                \
+       SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 6, __val)
+
+
+#define SET_TX_DESC_WHEADER_LEN(__pdesc, __val)        \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 4, __val)
+#define SET_TX_DESC_CHK_EN(__pdesc, __val)             \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 4, 1, __val)
+#define SET_TX_DESC_EARLY_MODE(__pdesc, __val)                 \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 5, 1, __val)
+#define SET_TX_DESC_HWSEQ_SEL(__pdesc, __val)          \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 6, 2, __val)
+#define SET_TX_DESC_USE_RATE(__pdesc, __val)           \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 1, __val)
+#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val)             \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 9, 1, __val)
+#define SET_TX_DESC_DISABLE_FB(__pdesc, __val)                 \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 10, 1, __val)
+#define SET_TX_DESC_CTS2SELF(__pdesc, __val)           \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 11, 1, __val)
+#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val)                 \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 12, 1, __val)
+#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val)              \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 13, 1, __val)
+#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val)                \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 15, 1, __val)
+#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val)                \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 1, __val)
+#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val)                \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 17, 5, __val)
+#define SET_TX_DESC_NDPA(__pdesc, __val)               \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 22, 2, __val)
+#define SET_TX_DESC_AMPDU_MAX_TIME(__pdesc, __val)             \
+       SET_BITS_TO_LE_4BYTE(__pdesc+12, 24, 8, __val)
+#define SET_TX_DESC_TX_ANT(__pdesc, __val)             \
+       SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 4, __val)
+
+#define SET_TX_DESC_TX_RATE(__pdesc, __val)            \
+       SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 7, __val)
+#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val)                 \
+       SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 5, __val)
+#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val)          \
+       SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 4, __val)
+#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val)                         \
+       SET_BITS_TO_LE_4BYTE(__pdesc+16, 17, 1, __val)
+#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val)           \
+       SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 6, __val)
+#define SET_TX_DESC_RTS_RATE(__pdesc, __val)           \
+       SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 5, __val)
+
+
+#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val)             \
+       SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 4, __val)
+#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val)       \
+       SET_BITS_TO_LE_1BYTE(__pdesc+20, 6, 1, __val)
+#define SET_TX_DESC_DATA_BW(__pdesc, __val)            \
+       SET_BITS_TO_LE_4BYTE(__pdesc+20, 5, 2, __val)
+#define SET_TX_DESC_DATA_LDPC(__pdesc, __val)  \
+       SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
+#define SET_TX_DESC_DATA_STBC(__pdesc, __val)  \
+       SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 2, __val)
+#define SET_TX_DESC_CTROL_STBC(__pdesc, __val)         \
+       SET_BITS_TO_LE_4BYTE(__pdesc+20, 10, 2, __val)
+#define SET_TX_DESC_RTS_SHORT(__pdesc, __val)  \
+       SET_BITS_TO_LE_4BYTE(__pdesc+20, 12, 1, __val)
+#define SET_TX_DESC_RTS_SC(__pdesc, __val)     \
+       SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
+
+
+#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val)     \
+       SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
+
+#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc)            \
+       LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
+
+#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val)   \
+       SET_BITS_TO_LE_4BYTE(__pdesc+32, 15, 1, __val)
+
+#define SET_TX_DESC_SEQ(__pdesc, __val)        \
+       SET_BITS_TO_LE_4BYTE(__pdesc+36, 12, 12, __val)
+
+#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val)  \
+       SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
+
+#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc)                 \
+       LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
+
+
+#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val)  \
+       SET_BITS_TO_LE_4BYTE(__pdesc+48, 0, 32, __val)
+
+#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc)                 \
+       LE_BITS_TO_4BYTE(__pdesc+48, 0, 32)
+
+#define GET_RX_DESC_PKT_LEN(__pdesc)                   \
+       LE_BITS_TO_4BYTE(__pdesc, 0, 14)
+#define GET_RX_DESC_CRC32(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc, 14, 1)
+#define GET_RX_DESC_ICV(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc, 15, 1)
+#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc)             \
+       LE_BITS_TO_4BYTE(__pdesc, 16, 4)
+#define GET_RX_DESC_SECURITY(__pdesc)                  \
+       LE_BITS_TO_4BYTE(__pdesc, 20, 3)
+#define GET_RX_DESC_QOS(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc, 23, 1)
+#define GET_RX_DESC_SHIFT(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc, 24, 2)
+#define GET_RX_DESC_PHYST(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc, 26, 1)
+#define GET_RX_DESC_SWDEC(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc, 27, 1)
+#define GET_RX_DESC_LS(__pdesc)                                \
+       LE_BITS_TO_4BYTE(__pdesc, 28, 1)
+#define GET_RX_DESC_FS(__pdesc)                                \
+       LE_BITS_TO_4BYTE(__pdesc, 29, 1)
+#define GET_RX_DESC_EOR(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc, 30, 1)
+#define GET_RX_DESC_OWN(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc, 31, 1)
+
+#define SET_RX_DESC_PKT_LEN(__pdesc, __val)    \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
+#define SET_RX_DESC_EOR(__pdesc, __val)                \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
+#define SET_RX_DESC_OWN(__pdesc, __val)                \
+       SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
+
+#define GET_RX_DESC_MACID(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc+4, 0, 7)
+#define GET_RX_DESC_TID(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc+4, 8, 4)
+#define GET_RX_DESC_AMSDU(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
+#define GET_RX_STATUS_DESC_RXID_MATCH(__pdesc)                                 \
+       LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
+#define GET_RX_DESC_PAGGR(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
+#define GET_RX_DESC_A1_FIT(__pdesc)                    \
+       LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
+#define GET_RX_DESC_CHKERR(__pdesc)                    \
+       LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
+#define GET_RX_DESC_IPVER(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
+#define GET_RX_STATUS_DESC_IS_TCPUDP(__pdesc)                          \
+       LE_BITS_TO_4BYTE(__pdesc+4, 22, 1)
+#define GET_RX_STATUS_DESC_CHK_VLD(__pdesc)                            \
+       LE_BITS_TO_4BYTE(__pdesc+4, 23, 1)
+#define GET_RX_DESC_PAM(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
+#define GET_RX_DESC_PWR(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
+#define GET_RX_DESC_MD(__pdesc)                                \
+       LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
+#define GET_RX_DESC_MF(__pdesc)                                \
+       LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
+#define GET_RX_DESC_TYPE(__pdesc)                              \
+       LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
+#define GET_RX_DESC_MC(__pdesc)                                \
+       LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
+#define GET_RX_DESC_BC(__pdesc)                                \
+       LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
+
+
+#define GET_RX_DESC_SEQ(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
+#define GET_RX_DESC_FRAG(__pdesc)                              \
+       LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
+#define GET_RX_STATUS_DESC_RX_IS_QOS(__pdesc)                          \
+       LE_BITS_TO_4BYTE(__pdesc+8, 16, 1)
+#define GET_RX_STATUS_DESC_WLANHD_IV_LEN(__pdesc)                              \
+       LE_BITS_TO_4BYTE(__pdesc+8, 18, 6)
+#define GET_RX_STATUS_DESC_RPT_SEL(__pdesc)                            \
+       LE_BITS_TO_4BYTE(__pdesc+8, 28, 1)
+
+
+#define GET_RX_DESC_RXMCS(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc+12, 0, 7)
+#define GET_RX_DESC_RXHT(__pdesc)                              \
+       LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
+#define GET_RX_STATUS_DESC_RX_GF(__pdesc)                              \
+       LE_BITS_TO_4BYTE(__pdesc+12, 7, 1)
+#define GET_RX_DESC_HTC(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
+#define GET_RX_STATUS_DESC_EOSP(__pdesc)               \
+       LE_BITS_TO_4BYTE( __pdesc+12, 11, 1)
+#define GET_RX_STATUS_DESC_BSSID_FIT(__pdesc)          \
+       LE_BITS_TO_4BYTE( __pdesc+12, 12, 2)
+
+#define GET_RX_STATUS_DESC_PATTERN_MATCH(__pdesc)      \
+       LE_BITS_TO_4BYTE( __pdesc+12, 29, 1)
+#define GET_RX_STATUS_DESC_UNICAST_MATCH(__pdesc)      \
+       LE_BITS_TO_4BYTE( __pdesc+12, 30, 1)
+#define GET_RX_STATUS_DESC_MAGIC_MATCH(__pdesc)        \
+       LE_BITS_TO_4BYTE( __pdesc+12, 31, 1)
+
+#define GET_RX_DESC_SPLCP(__pdesc)                             \
+       LE_BITS_TO_4BYTE(__pdesc+16, 0, 1)
+#define GET_RX_STATUS_DESC_LDPC(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc+16, 1, 1)
+#define GET_RX_STATUS_DESC_STBC(__pdesc)                               \
+       LE_BITS_TO_4BYTE(__pdesc+16, 2, 1)
+#define GET_RX_DESC_BW(__pdesc)                                \
+       LE_BITS_TO_4BYTE(__pdesc+16, 4, 2)
+
+#define GET_RX_DESC_TSFL(__pdesc)                              \
+       LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
+
+#define GET_RX_DESC_BUFF_ADDR(__pdesc)                         \
+       LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
+#define GET_RX_DESC_BUFF_ADDR64(__pdesc)               \
+       LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
+
+#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val)  \
+       SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
+#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
+       SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
+
+
+/* TX report 2 format in Rx desc*/
+
+#define GET_RX_RPT2_DESC_PKT_LEN(__pRxStatusDesc)      \
+       LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 9)
+#define GET_RX_RPT2_DESC_MACID_VALID_1(__pRxStatusDesc)        \
+       LE_BITS_TO_4BYTE( __pRxStatusDesc+16, 0, 32)
+#define GET_RX_RPT2_DESC_MACID_VALID_2(__pRxStatusDesc)        \
+       LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32)
+
+#define SET_EARLYMODE_PKTNUM(__paddr, __value)         \
+       SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __value)
+#define SET_EARLYMODE_LEN0(__paddr, __value)   \
+       SET_BITS_TO_LE_4BYTE(__paddr, 4, 12, __value)
+#define SET_EARLYMODE_LEN1(__paddr, __value)   \
+       SET_BITS_TO_LE_4BYTE(__paddr, 16, 12, __value)
+#define SET_EARLYMODE_LEN2_1(__paddr, __value)         \
+       SET_BITS_TO_LE_4BYTE(__paddr, 28, 4, __value)
+#define SET_EARLYMODE_LEN2_2(__paddr, __value)         \
+       SET_BITS_TO_LE_4BYTE(__paddr+4, 0, 8, __value)
+#define SET_EARLYMODE_LEN3(__paddr, __value)   \
+       SET_BITS_TO_LE_4BYTE(__paddr+4, 8, 12, __value)
+#define SET_EARLYMODE_LEN4(__paddr, __value)   \
+       SET_BITS_TO_LE_4BYTE(__paddr+4, 20, 12, __value)
+
+#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size)              \
+do {                                                           \
+       if(_size > TX_DESC_NEXT_DESC_OFFSET)                    \
+               memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET);   \
+       else                                                    \
+               memset(__pdesc, 0, _size);                      \
+} while (0);
+
+#define RX_HAL_IS_CCK_RATE(rxmcs)\
+       (rxmcs == DESC_RATE1M ||\
+        rxmcs == DESC_RATE2M ||\
+        rxmcs == DESC_RATE5_5M ||\
+        rxmcs == DESC_RATE11M)
+
+#define IS_LITTLE_ENDIAN       1
+
+struct phy_rx_agc_info_t {
+       #if IS_LITTLE_ENDIAN
+               u8      gain:7,trsw:1;
+       #else
+               u8      trsw:1,gain:7;
+       #endif
+};
+struct phy_status_rpt{
+       struct phy_rx_agc_info_t path_agc[2];
+       u8      ch_corr[2];
+       u8      cck_sig_qual_ofdm_pwdb_all;
+       u8      cck_agc_rpt_ofdm_cfosho_a;
+       u8      cck_rpt_b_ofdm_cfosho_b;
+       u8      rsvd_1;//ch_corr_msb;
+       u8      noise_power_db_msb;
+       u8      path_cfotail[2];
+       u8      pcts_mask[2];
+       u8      stream_rxevm[2];
+       u8      path_rxsnr[2];
+       u8      noise_power_db_lsb;
+       u8      rsvd_2[3];
+       u8      stream_csi[2];
+       u8      stream_target_csi[2];
+       u8      sig_evm;
+       u8      rsvd_3;
+#if IS_LITTLE_ENDIAN
+       u8      antsel_rx_keep_2:1;     /*ex_intf_flg:1;*/
+       u8      sgi_en:1;
+       u8      rxsc:2;
+       u8      idle_long:1;
+       u8      r_ant_train_en:1;
+       u8      ant_sel_b:1;
+       u8      ant_sel:1;
+#else  /* _BIG_ENDIAN_ */
+       u8      ant_sel:1;
+       u8      ant_sel_b:1;
+       u8      r_ant_train_en:1;
+       u8      idle_long:1;
+       u8      rxsc:2;
+       u8      sgi_en:1;
+       u8      antsel_rx_keep_2:1;     /*ex_intf_flg:1;*/
+#endif
+}__packed;
+
+struct rx_fwinfo_8821ae {
+       u8 gain_trsw[4];
+       u8 pwdb_all;
+       u8 cfosho[4];
+       u8 cfotail[4];
+       char rxevm[2];
+       char rxsnr[4];
+       u8 pdsnr[2];
+       u8 csi_current[2];
+       u8 csi_target[2];
+       u8 sigevm;
+       u8 max_ex_pwr;
+       u8 ex_intf_flag:1;
+       u8 sgi_en:1;
+       u8 rxsc:2;
+       u8 reserve:4;
+} __packed;
+
+struct tx_desc_8821ae {
+       u32 pktsize:16;
+       u32 offset:8;
+       u32 bmc:1;
+       u32 htc:1;
+       u32 lastseg:1;
+       u32 firstseg:1;
+       u32 linip:1;
+       u32 noacm:1;
+       u32 gf:1;
+       u32 own:1;
+
+       u32 macid:6;
+       u32 rsvd0:2;
+       u32 queuesel:5;
+       u32 rd_nav_ext:1;
+       u32 lsig_txop_en:1;
+       u32 pifs:1;
+       u32 rateid:4;
+       u32 nav_usehdr:1;
+       u32 en_descid:1;
+       u32 sectype:2;
+       u32 pktoffset:8;
+
+       u32 rts_rc:6;
+       u32 data_rc:6;
+       u32 agg_en:1;
+       u32 rdg_en:1;
+       u32 bar_retryht:2;
+       u32 agg_break:1;
+       u32 morefrag:1;
+       u32 raw:1;
+       u32 ccx:1;
+       u32 ampdudensity:3;
+       u32 bt_int:1;
+       u32 ant_sela:1;
+       u32 ant_selb:1;
+       u32 txant_cck:2;
+       u32 txant_l:2;
+       u32 txant_ht:2;
+
+       u32 nextheadpage:8;
+       u32 tailpage:8;
+       u32 seq:12;
+       u32 cpu_handle:1;
+       u32 tag1:1;
+       u32 trigger_int:1;
+       u32 hwseq_en:1;
+
+       u32 rtsrate:5;
+       u32 apdcfe:1;
+       u32 qos:1;
+       u32 hwseq_ssn:1;
+       u32 userrate:1;
+       u32 dis_rtsfb:1;
+       u32 dis_datafb:1;
+       u32 cts2self:1;
+       u32 rts_en:1;
+       u32 hwrts_en:1;
+       u32 portid:1;
+       u32 pwr_status:3;
+       u32 waitdcts:1;
+       u32 cts2ap_en:1;
+       u32 txsc:2;
+       u32 stbc:2;
+       u32 txshort:1;
+       u32 txbw:1;
+       u32 rtsshort:1;
+       u32 rtsbw:1;
+       u32 rtssc:2;
+       u32 rtsstbc:2;
+
+       u32 txrate:6;
+       u32 shortgi:1;
+       u32 ccxt:1;
+       u32 txrate_fb_lmt:5;
+       u32 rtsrate_fb_lmt:4;
+       u32 retrylmt_en:1;
+       u32 txretrylmt:6;
+       u32 usb_txaggnum:8;
+
+       u32 txagca:5;
+       u32 txagcb:5;
+       u32 usemaxlen:1;
+       u32 maxaggnum:5;
+       u32 mcsg1maxlen:4;
+       u32 mcsg2maxlen:4;
+       u32 mcsg3maxlen:4;
+       u32 mcs7sgimaxlen:4;
+
+       u32 txbuffersize:16;
+       u32 sw_offset30:8;
+       u32 sw_offset31:4;
+       u32 rsvd1:1;
+       u32 antsel_c:1;
+       u32 null_0:1;
+       u32 null_1:1;
+
+       u32 txbuffaddr;
+       u32 txbufferaddr64;
+       u32 nextdescaddress;
+       u32 nextdescaddress64;
+
+       u32 reserve_pass_pcie_mm_limit[4];
+} __packed;
+
+struct rx_desc_8821ae {
+       u32 length:14;
+       u32 crc32:1;
+       u32 icverror:1;
+       u32 drv_infosize:4;
+       u32 security:3;
+       u32 qos:1;
+       u32 shift:2;
+       u32 phystatus:1;
+       u32 swdec:1;
+       u32 lastseg:1;
+       u32 firstseg:1;
+       u32 eor:1;
+       u32 own:1;
+
+       u32 macid:6;
+       u32 tid:4;
+       u32 hwrsvd:5;
+       u32 paggr:1;
+       u32 faggr:1;
+       u32 a1_fit:4;
+       u32 a2_fit:4;
+       u32 pam:1;
+       u32 pwr:1;
+       u32 moredata:1;
+       u32 morefrag:1;
+       u32 type:2;
+       u32 mc:1;
+       u32 bc:1;
+
+       u32 seq:12;
+       u32 frag:4;
+       u32 nextpktlen:14;
+       u32 nextind:1;
+       u32 rsvd:1;
+
+       u32 rxmcs:6;
+       u32 rxht:1;
+       u32 amsdu:1;
+       u32 splcp:1;
+       u32 bandwidth:1;
+       u32 htc:1;
+       u32 tcpchk_rpt:1;
+       u32 ipcchk_rpt:1;
+       u32 tcpchk_valid:1;
+       u32 hwpcerr:1;
+       u32 hwpcind:1;
+       u32 iv0:16;
+
+       u32 iv1;
+
+       u32 tsfl;
+
+       u32 bufferaddress;
+       u32 bufferaddress64;
+
+} __packed;
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw,
+                         struct ieee80211_hdr *hdr, u8 *pdesc_tx, u8 *txbd,
+                         struct ieee80211_tx_info *info, struct sk_buff *skb,
+                         u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
+#else
+/*<delete in kernel end>*/
+void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw,
+                         struct ieee80211_hdr *hdr, u8 *pdesc_tx, u8 *txbd,
+                         struct ieee80211_tx_info *info,
+                         struct ieee80211_sta *sta,
+                         struct sk_buff *skb,
+                         u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+bool rtl8821ae_rx_query_desc(struct ieee80211_hw *hw,
+                          struct rtl_stats *status,
+                          struct ieee80211_rx_status *rx_status,
+                          u8 *pdesc, struct sk_buff *skb);
+void rtl8821ae_set_desc(struct ieee80211_hw * hw, u8 *pdesc, bool istx, u8 desc_name, u8 *val);
+u32 rtl8821ae_get_desc(u8 *pdesc, bool istx, u8 desc_name);
+bool rtl8821ae_is_tx_desc_closed(struct ieee80211_hw *hw,
+                                u8 hw_queue, u16 index);
+void rtl8821ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
+void rtl8821ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
+                            bool b_firstseg, bool b_lastseg,
+                            struct sk_buff *skb);
+#endif
diff --git a/drivers/staging/rtl8821ae/stats.c b/drivers/staging/rtl8821ae/stats.c
new file mode 100644 (file)
index 0000000..a20c0f8
--- /dev/null
@@ -0,0 +1,283 @@
+/******************************************************************************
+ *
+ * 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 "wifi.h"
+#include "stats.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+#include <linux/export.h>
+#endif
+
+u8 rtl_query_rxpwrpercentage(char antpower)
+{
+       if ((antpower <= -100) || (antpower >= 20))
+               return 0;
+       else if (antpower >= 0)
+               return 100;
+       else
+               return (100 + antpower);
+}
+//EXPORT_SYMBOL(rtl_query_rxpwrpercentage);
+
+u8 rtl_evm_db_to_percentage(char value)
+{
+       char ret_val;
+       ret_val = value;
+
+       if (ret_val >= 0)
+               ret_val = 0;
+       if (ret_val <= -33)
+               ret_val = -33;
+       ret_val = 0 - ret_val;
+       ret_val *= 3;
+       if (ret_val == 99)
+               ret_val = 100;
+
+       return ret_val;
+}
+//EXPORT_SYMBOL(rtl_evm_db_to_percentage);
+
+long rtl_translate_todbm(struct ieee80211_hw *hw,
+                        u8 signal_strength_index)
+{
+       long signal_power;
+
+       signal_power = (long)((signal_strength_index + 1) >> 1);
+       signal_power -= 95;
+       return signal_power;
+}
+
+long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig)
+{
+       long retsig;
+
+       if (currsig >= 61 && currsig <= 100)
+               retsig = 90 + ((currsig - 60) / 4);
+       else if (currsig >= 41 && currsig <= 60)
+               retsig = 78 + ((currsig - 40) / 2);
+       else if (currsig >= 31 && currsig <= 40)
+               retsig = 66 + (currsig - 30);
+       else if (currsig >= 21 && currsig <= 30)
+               retsig = 54 + (currsig - 20);
+       else if (currsig >= 5 && currsig <= 20)
+               retsig = 42 + (((currsig - 5) * 2) / 3);
+       else if (currsig == 4)
+               retsig = 36;
+       else if (currsig == 3)
+               retsig = 27;
+       else if (currsig == 2)
+               retsig = 18;
+       else if (currsig == 1)
+               retsig = 9;
+       else
+               retsig = currsig;
+
+       return retsig;
+}
+//EXPORT_SYMBOL(rtl_signal_scale_mapping);
+
+void rtl_process_ui_rssi(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 rfpath;
+       u32 last_rssi, tmpval;
+
+       if (!pstatus->b_packet_toself && !pstatus->b_packet_beacon)
+               return;
+
+       rtlpriv->stats.pwdb_all_cnt += pstatus->rx_pwdb_all;
+       rtlpriv->stats.rssi_calculate_cnt++;
+
+       if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) {
+               rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX;
+               last_rssi = rtlpriv->stats.ui_rssi.elements[
+                       rtlpriv->stats.ui_rssi.index];
+               rtlpriv->stats.ui_rssi.total_val -= last_rssi;
+       }
+       rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength;
+       rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] =
+           pstatus->signalstrength;
+       if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
+               rtlpriv->stats.ui_rssi.index = 0;
+       tmpval = rtlpriv->stats.ui_rssi.total_val /
+               rtlpriv->stats.ui_rssi.total_num;
+       rtlpriv->stats.signal_strength = rtl_translate_todbm(hw,
+               (u8) tmpval);
+       pstatus->rssi = rtlpriv->stats.signal_strength;
+
+       if (pstatus->b_is_cck)
+               return;
+
+       for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+            rfpath++) {
+               if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
+                       rtlpriv->stats.rx_rssi_percentage[rfpath] =
+                           pstatus->rx_mimo_signalstrength[rfpath];
+
+               }
+               if (pstatus->rx_mimo_signalstrength[rfpath] >
+                   rtlpriv->stats.rx_rssi_percentage[rfpath]) {
+                       rtlpriv->stats.rx_rssi_percentage[rfpath] =
+                           ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
+                             (RX_SMOOTH_FACTOR - 1)) +
+                            (pstatus->rx_mimo_signalstrength[rfpath])) /
+                           (RX_SMOOTH_FACTOR);
+                       rtlpriv->stats.rx_rssi_percentage[rfpath] =
+                           rtlpriv->stats.rx_rssi_percentage[rfpath] + 1;
+               } else {
+                       rtlpriv->stats.rx_rssi_percentage[rfpath] =
+                           ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
+                             (RX_SMOOTH_FACTOR - 1)) +
+                            (pstatus->rx_mimo_signalstrength[rfpath])) /
+                           (RX_SMOOTH_FACTOR);
+               }
+               rtlpriv->stats.rx_snr_db[rfpath] = pstatus->rx_snr[rfpath];
+               rtlpriv->stats.rx_evm_dbm[rfpath] =
+                                       pstatus->rx_mimo_evm_dbm[rfpath];
+               rtlpriv->stats.rx_cfo_short[rfpath] =
+                                       pstatus->cfo_short[rfpath];
+               rtlpriv->stats.rx_cfo_tail[rfpath] = pstatus->cfo_tail[rfpath];
+       }
+}
+
+static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw,
+                                         struct rtl_stats *pstatus)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int weighting = 0;
+
+       if (rtlpriv->stats.recv_signal_power == 0)
+               rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower;
+       if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power)
+               weighting = 5;
+       else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power)
+               weighting = (-5);
+       rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power *
+               5 + pstatus->recvsignalpower + weighting) / 6;
+}
+
+static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_sta_info *drv_priv = NULL;
+       struct ieee80211_sta *sta = NULL;
+       long undecorated_smoothed_pwdb;
+
+       rcu_read_lock();
+       if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
+               sta = rtl_find_sta(hw, pstatus->psaddr);
+
+       /* adhoc or ap mode */
+       if (sta) {
+               drv_priv = (struct rtl_sta_info *) sta->drv_priv;
+               undecorated_smoothed_pwdb =
+                       drv_priv->rssi_stat.undecorated_smoothed_pwdb;
+       } else {
+               undecorated_smoothed_pwdb =
+                       rtlpriv->dm.undecorated_smoothed_pwdb;
+       }
+
+       if (undecorated_smoothed_pwdb < 0)
+               undecorated_smoothed_pwdb = pstatus->rx_pwdb_all;
+       if (pstatus->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
+               undecorated_smoothed_pwdb = (((undecorated_smoothed_pwdb) *
+                     (RX_SMOOTH_FACTOR - 1)) +
+                    (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+               undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + 1;
+       } else {
+               undecorated_smoothed_pwdb = (((undecorated_smoothed_pwdb) *
+                     (RX_SMOOTH_FACTOR - 1)) +
+                    (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+       }
+
+       if(sta) {
+               drv_priv->rssi_stat.undecorated_smoothed_pwdb =
+                       undecorated_smoothed_pwdb;
+       } else {
+               rtlpriv->dm.undecorated_smoothed_pwdb = undecorated_smoothed_pwdb;
+       }
+       rcu_read_unlock();
+
+       rtl_update_rxsignalstatistics(hw, pstatus);
+}
+
+static void rtl_process_ui_link_quality(struct ieee80211_hw *hw,
+                                       struct rtl_stats *pstatus)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 last_evm, n_stream, tmpval;
+
+       if (pstatus->signalquality == 0)
+               return;
+
+       if (rtlpriv->stats.ui_link_quality.total_num++ >=
+           PHY_LINKQUALITY_SLID_WIN_MAX) {
+               rtlpriv->stats.ui_link_quality.total_num =
+                   PHY_LINKQUALITY_SLID_WIN_MAX;
+               last_evm = rtlpriv->stats.ui_link_quality.elements[
+                       rtlpriv->stats.ui_link_quality.index];
+               rtlpriv->stats.ui_link_quality.total_val -= last_evm;
+       }
+       rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality;
+       rtlpriv->stats.ui_link_quality.elements[
+               rtlpriv->stats.ui_link_quality.index++] =
+                                                       pstatus->signalquality;
+       if (rtlpriv->stats.ui_link_quality.index >=
+           PHY_LINKQUALITY_SLID_WIN_MAX)
+               rtlpriv->stats.ui_link_quality.index = 0;
+       tmpval = rtlpriv->stats.ui_link_quality.total_val /
+           rtlpriv->stats.ui_link_quality.total_num;
+       rtlpriv->stats.signal_quality = tmpval;
+       rtlpriv->stats.last_sigstrength_inpercent = tmpval;
+       for (n_stream = 0; n_stream < 2; n_stream++) {
+               if (pstatus->rx_mimo_signalquality[n_stream] != -1) {
+                       if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) {
+                               rtlpriv->stats.rx_evm_percentage[n_stream] =
+                                   pstatus->rx_mimo_signalquality[n_stream];
+                       }
+                       rtlpriv->stats.rx_evm_percentage[n_stream] =
+                           ((rtlpriv->stats.rx_evm_percentage[n_stream]
+                             * (RX_SMOOTH_FACTOR - 1)) +
+                            (pstatus->rx_mimo_signalquality[n_stream] * 1)) /
+                           (RX_SMOOTH_FACTOR);
+               }
+       }
+}
+
+void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer,
+                        struct rtl_stats *pstatus)
+{
+
+       if (!pstatus->b_packet_matchbssid)
+               return;
+
+       rtl_process_ui_rssi(hw, pstatus);
+       rtl_process_pwdb(hw, pstatus);
+       rtl_process_ui_link_quality(hw, pstatus);
+}
+//EXPORT_SYMBOL(rtl_process_phyinfo);
diff --git a/drivers/staging/rtl8821ae/stats.h b/drivers/staging/rtl8821ae/stats.h
new file mode 100644 (file)
index 0000000..d69d0cf
--- /dev/null
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * 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_STATS_H__
+#define __RTL_STATS_H__
+
+#define        PHY_RSSI_SLID_WIN_MAX                   100
+#define        PHY_LINKQUALITY_SLID_WIN_MAX            20
+#define        PHY_BEACON_RSSI_SLID_WIN_MAX            10
+
+/* Rx smooth factor */
+#define        RX_SMOOTH_FACTOR                        20
+
+u8 rtl_query_rxpwrpercentage(char antpower);
+u8 rtl_evm_db_to_percentage(char value);
+long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig);
+void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer,
+                        struct rtl_stats *pstatus);
+
+#endif
diff --git a/drivers/staging/rtl8821ae/wifi.h b/drivers/staging/rtl8821ae/wifi.h
new file mode 100644 (file)
index 0000000..cfe88a1
--- /dev/null
@@ -0,0 +1,2532 @@
+/******************************************************************************
+ *
+ * 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_WIFI_H__
+#define __RTL_WIFI_H__
+
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/firmware.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "debug.h"
+
+
+#define RF_CHANGE_BY_INIT              0
+#define RF_CHANGE_BY_IPS               BIT(28)
+#define RF_CHANGE_BY_PS                BIT(29)
+#define RF_CHANGE_BY_HW                BIT(30)
+#define RF_CHANGE_BY_SW                BIT(31)
+
+#define IQK_ADDA_REG_NUM               16
+#define IQK_MAC_REG_NUM                        4
+#define IQK_THRESHOLD                  8
+
+#define MAX_KEY_LEN                    61
+#define KEY_BUF_SIZE                   5
+
+/* QoS related. */
+/*aci: 0x00    Best Effort*/
+/*aci: 0x01    Background*/
+/*aci: 0x10    Video*/
+/*aci: 0x11    Voice*/
+/*Max: define total number.*/
+#define AC0_BE                         0
+#define AC1_BK                         1
+#define AC2_VI                         2
+#define AC3_VO                         3
+#define AC_MAX                         4
+#define QOS_QUEUE_NUM                  4
+#define RTL_MAC80211_NUM_QUEUE         5
+
+#define QBSS_LOAD_SIZE                 5
+#define MAX_WMMELE_LENGTH              64
+
+#define TOTAL_CAM_ENTRY                32
+
+/*slot time for 11g. */
+#define RTL_SLOT_TIME_9                        9
+#define RTL_SLOT_TIME_20               20
+
+/*related with tcp/ip. */
+/*if_ehther.h*/
+#define ETH_P_PAE                      0x888E  /*Port Access Entity
+                                                *(IEEE 802.1X) */
+#define ETH_P_IP                       0x0800  /*Internet Protocol packet */
+#define ETH_P_ARP                      0x0806  /*Address Resolution packet */
+#define SNAP_SIZE                      6
+#define PROTOC_TYPE_SIZE               2
+
+/*related with 802.11 frame*/
+#define MAC80211_3ADDR_LEN             24
+#define MAC80211_4ADDR_LEN             30
+
+#define CHANNEL_MAX_NUMBER             (14 + 24 + 21)  /* 14 is the max
+                                                        * channel number */
+#define CHANNEL_MAX_NUMBER_2G          14
+#define CHANNEL_MAX_NUMBER_5G          54 /* Please refer to
+                                           *"phy_GetChnlGroup8812A" and
+                                           * "Hal_ReadTxPowerInfo8812A"*/
+#define CHANNEL_MAX_NUMBER_5G_80M      7
+#define CHANNEL_GROUP_MAX              (3 + 9) /* ch1~3, ch4~9, ch10~14
+                                                * total three groups */
+#define MAX_PG_GROUP                   13
+#define        CHANNEL_GROUP_MAX_2G            3
+#define        CHANNEL_GROUP_IDX_5GL           3
+#define        CHANNEL_GROUP_IDX_5GM           6
+#define        CHANNEL_GROUP_IDX_5GH           9
+#define        CHANNEL_GROUP_MAX_5G            9
+#define CHANNEL_MAX_NUMBER_2G          14
+#define AVG_THERMAL_NUM                        8
+#define AVG_THERMAL_NUM_92E            4
+#define AVG_THERMAL_NUM_88E            4
+#define AVG_THERMAL_NUM_8723BE         4
+#define MAX_TID_COUNT                  9
+#define MAX_NUM_RATES                  264
+
+/*for 88E use*/
+/*It must always set to 4, otherwise read efuse table secquence will be wrong.*/
+#define MAX_TX_COUNT                   4
+#define        MAX_RF_PATH                     4
+#define        MAX_CHNL_GROUP_24G              6
+#define        MAX_CHNL_GROUP_5G               14
+
+/* BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON. */
+#define MAX_TX_QUEUE                   9
+
+#define TX_PWR_BY_RATE_NUM_BAND                2
+#define TX_PWR_BY_RATE_NUM_RF          4
+#define TX_PWR_BY_RATE_NUM_SECTION     12
+#define MAX_BASE_NUM_IN_PHY_REG_PG_24G  6
+#define MAX_BASE_NUM_IN_PHY_REG_PG_5G  5
+
+#define DELTA_SWINGIDX_SIZE    30
+#define BAND_NUM                               3
+/*Now, it's just for 8192ee
+ *not OK yet, keep it 0*/
+#define DMA_IS_64BIT 0
+#define RTL8192EE_SEG_NUM              1 /* 0:2 seg, 1: 4 seg, 2: 8 seg */
+
+struct txpower_info_2g {
+       u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
+       u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
+       /*If only one tx, only BW20 and OFDM are used.*/
+       u8 cck_diff[MAX_RF_PATH][MAX_TX_COUNT];
+       u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];
+       u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];
+       u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT];
+};
+
+struct txpower_info_5g {
+       u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_5G];
+       /*If only one tx, only BW20, OFDM, BW80 and BW160 are used.*/
+       u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];
+       u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];
+       u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT];
+       u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT];
+       u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT];
+};
+
+
+/* for early mode */
+#define EM_HDR_LEN                     8
+#define FCS_LEN                                4
+
+#define MAX_VIRTUAL_MAC                        1
+
+enum rf_tx_num {
+       RF_1TX = 0,
+       RF_2TX,
+       RF_MAX_TX_NUM,
+       RF_TX_NUM_NONIMPLEMENT,
+};
+
+enum rate_section {
+       CCK = 0,
+       OFDM,
+       HT_MCS0_MCS7,
+       HT_MCS8_MCS15,
+       VHT_1SSMCS0_1SSMCS9,
+       VHT_2SSMCS0_2SSMCS9,
+};
+
+enum intf_type {
+       INTF_PCI = 0,
+       INTF_USB = 1,
+};
+
+enum radio_path {
+       RF90_PATH_A = 0,
+       RF90_PATH_B = 1,
+       RF90_PATH_C = 2,
+       RF90_PATH_D = 3,
+};
+
+enum rt_eeprom_type {
+       EEPROM_93C46,
+       EEPROM_93C56,
+       EEPROM_BOOT_EFUSE,
+};
+
+enum rtl_status {
+       RTL_STATUS_INTERFACE_START = 0,
+};
+
+enum hardware_type {
+       HARDWARE_TYPE_RTL8192E,
+       HARDWARE_TYPE_RTL8192U,
+       HARDWARE_TYPE_RTL8192SE,
+       HARDWARE_TYPE_RTL8192SU,
+       HARDWARE_TYPE_RTL8192CE,
+       HARDWARE_TYPE_RTL8192CU,
+       HARDWARE_TYPE_RTL8192DE,
+       HARDWARE_TYPE_RTL8192DU,
+       HARDWARE_TYPE_RTL8723AE,
+       HARDWARE_TYPE_RTL8188EE,
+       HARDWARE_TYPE_RTL8723BE,
+       HARDWARE_TYPE_RTL8192EE,
+       HARDWARE_TYPE_RTL8821AE,
+       HARDWARE_TYPE_RTL8812AE,
+       /* keep it last */
+       HARDWARE_TYPE_NUM
+};
+
+enum scan_operation_backup_opt {
+       SCAN_OPT_BACKUP_BAND0=0,
+       SCAN_OPT_BACKUP_BAND1,
+       SCAN_OPT_RESTORE,
+       SCAN_OPT_MAX
+};
+
+/*RF state.*/
+enum rf_pwrstate {
+       ERFON,
+       ERFSLEEP,
+       ERFOFF
+};
+
+struct bb_reg_def {
+       u32 rfintfs;
+       u32 rfintfi;
+       u32 rfintfo;
+       u32 rfintfe;
+       u32 rf3wire_offset;
+       u32 rflssi_select;
+       u32 rftxgain_stage;
+       u32 rfhssi_para1;
+       u32 rfhssi_para2;
+       u32 rfswitch_control;
+       u32 rfagc_control1;
+       u32 rfagc_control2;
+       u32 rfrxiq_imbalance;
+       u32 rfrx_afe;
+       u32 rftxiq_imbalance;
+       u32 rftx_afe;
+       u32 rflssi_readback;
+       u32 rflssi_readbackpi;
+};
+
+enum io_type {
+       IO_CMD_PAUSE_BAND0_DM_BY_SCAN = 0,
+       IO_CMD_PAUSE_BAND1_DM_BY_SCAN = 1,
+       IO_CMD_RESUME_DM_BY_SCAN = 2,
+};
+
+enum hw_variables {
+       HW_VAR_ETHER_ADDR,
+       HW_VAR_MULTICAST_REG,
+       HW_VAR_BASIC_RATE,
+       HW_VAR_BSSID,
+       HW_VAR_MEDIA_STATUS,
+       HW_VAR_SECURITY_CONF,
+       HW_VAR_BEACON_INTERVAL,
+       HW_VAR_ATIM_WINDOW,
+       HW_VAR_LISTEN_INTERVAL,
+       HW_VAR_CS_COUNTER,
+       HW_VAR_DEFAULTKEY0,
+       HW_VAR_DEFAULTKEY1,
+       HW_VAR_DEFAULTKEY2,
+       HW_VAR_DEFAULTKEY3,
+       HW_VAR_SIFS,
+       HW_VAR_DIFS,
+       HW_VAR_EIFS,
+       HW_VAR_SLOT_TIME,
+       HW_VAR_ACK_PREAMBLE,
+       HW_VAR_CW_CONFIG,
+       HW_VAR_CW_VALUES,
+       HW_VAR_RATE_FALLBACK_CONTROL,
+       HW_VAR_CONTENTION_WINDOW,
+       HW_VAR_RETRY_COUNT,
+       HW_VAR_TR_SWITCH,
+       HW_VAR_COMMAND,
+       HW_VAR_WPA_CONFIG,
+       HW_VAR_AMPDU_MIN_SPACE,
+       HW_VAR_SHORTGI_DENSITY,
+       HW_VAR_AMPDU_FACTOR,
+       HW_VAR_MCS_RATE_AVAILABLE,
+       HW_VAR_AC_PARAM,
+       HW_VAR_ACM_CTRL,
+       HW_VAR_DIS_Req_Qsize,
+       HW_VAR_CCX_CHNL_LOAD,
+       HW_VAR_CCX_NOISE_HISTOGRAM,
+       HW_VAR_CCX_CLM_NHM,
+       HW_VAR_TxOPLimit,
+       HW_VAR_TURBO_MODE,
+       HW_VAR_RF_STATE,
+       HW_VAR_RF_OFF_BY_HW,
+       HW_VAR_BUS_SPEED,
+       HW_VAR_SET_DEV_POWER,
+
+       HW_VAR_RCR,
+       HW_VAR_RATR_0,
+       HW_VAR_RRSR,
+       HW_VAR_CPU_RST,
+       HW_VAR_CECHK_BSSID,
+       HW_VAR_LBK_MODE,
+       HW_VAR_AES_11N_FIX,
+       HW_VAR_USB_RX_AGGR,
+       HW_VAR_USER_CONTROL_TURBO_MODE,
+       HW_VAR_RETRY_LIMIT,
+       HW_VAR_INIT_TX_RATE,
+       HW_VAR_TX_RATE_REG,
+       HW_VAR_EFUSE_USAGE,
+       HW_VAR_EFUSE_BYTES,
+       HW_VAR_AUTOLOAD_STATUS,
+       HW_VAR_RF_2R_DISABLE,
+       HW_VAR_SET_RPWM,
+       HW_VAR_H2C_FW_PWRMODE,
+       HW_VAR_H2C_FW_JOINBSSRPT,
+       HW_VAR_H2C_FW_MEDIASTATUSRPT,
+       HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
+       HW_VAR_FW_PSMODE_STATUS,
+       HW_VAR_RESUME_CLK_ON,
+       HW_VAR_FW_LPS_ACTION,
+       HW_VAR_1X1_RECV_COMBINE,
+       HW_VAR_STOP_SEND_BEACON,
+       HW_VAR_TSF_TIMER,
+       HW_VAR_IO_CMD,
+
+       HW_VAR_RF_RECOVERY,
+       HW_VAR_H2C_FW_UPDATE_GTK,
+       HW_VAR_WF_MASK,
+       HW_VAR_WF_CRC,
+       HW_VAR_WF_IS_MAC_ADDR,
+       HW_VAR_H2C_FW_OFFLOAD,
+       HW_VAR_RESET_WFCRC,
+
+       HW_VAR_HANDLE_FW_C2H,
+       HW_VAR_DL_FW_RSVD_PAGE,
+       HW_VAR_AID,
+       HW_VAR_HW_SEQ_ENABLE,
+       HW_VAR_CORRECT_TSF,
+       HW_VAR_BCN_VALID,
+       HW_VAR_FWLPS_RF_ON,
+       HW_VAR_DUAL_TSF_RST,
+       HW_VAR_SWITCH_EPHY_WoWLAN,
+       HW_VAR_INT_MIGRATION,
+       HW_VAR_INT_AC,
+       HW_VAR_RF_TIMING,
+
+       HAL_DEF_WOWLAN,
+       HW_VAR_MRC,
+       HW_VAR_KEEP_ALIVE,
+       HW_VAR_NAV_UPPER,
+};
+
+enum rt_media_status {
+       RT_MEDIA_DISCONNECT = 0,
+       RT_MEDIA_CONNECT = 1
+};
+
+enum rt_oem_id {
+       RT_CID_DEFAULT = 0,
+       RT_CID_8187_ALPHA0 = 1,
+       RT_CID_8187_SERCOMM_PS = 2,
+       RT_CID_8187_HW_LED = 3,
+       RT_CID_8187_NETGEAR = 4,
+       RT_CID_WHQL = 5,
+       RT_CID_819x_CAMEO = 6,
+       RT_CID_819x_RUNTOP = 7,
+       RT_CID_819x_Senao = 8,
+       RT_CID_TOSHIBA = 9,
+       RT_CID_819x_Netcore = 10,
+       RT_CID_Nettronix = 11,
+       RT_CID_DLINK = 12,
+       RT_CID_PRONET = 13,
+       RT_CID_COREGA = 14,
+       RT_CID_819x_ALPHA = 15,
+       RT_CID_819x_Sitecom = 16,
+       RT_CID_CCX = 17,
+       RT_CID_819x_Lenovo = 18,
+       RT_CID_819x_QMI = 19,
+       RT_CID_819x_Edimax_Belkin = 20,
+       RT_CID_819x_Sercomm_Belkin = 21,
+       RT_CID_819x_CAMEO1 = 22,
+       RT_CID_819x_MSI = 23,
+       RT_CID_819x_Acer = 24,
+       RT_CID_819x_HP = 27,
+       RT_CID_819x_CLEVO = 28,
+       RT_CID_819x_Arcadyan_Belkin = 29,
+       RT_CID_819x_SAMSUNG = 30,
+       RT_CID_819x_WNC_COREGA = 31,
+       RT_CID_819x_Foxcoon = 32,
+       RT_CID_819x_DELL = 33,
+       RT_CID_819x_PRONETS = 34,
+       RT_CID_819x_Edimax_ASUS = 35,
+       RT_CID_NETGEAR = 36,
+       RT_CID_PLANEX = 37,
+       RT_CID_CC_C = 38,
+};
+
+enum hw_descs {
+       HW_DESC_OWN,
+       HW_DESC_RXOWN,
+       HW_DESC_TX_NEXTDESC_ADDR,
+       HW_DESC_TXBUFF_ADDR,
+       HW_DESC_RXBUFF_ADDR,
+       HW_DESC_RXPKT_LEN,
+       HW_DESC_RXERO,
+       HW_DESC_RX_PREPARE,
+};
+
+enum prime_sc {
+       PRIME_CHNL_OFFSET_DONT_CARE = 0,
+       PRIME_CHNL_OFFSET_LOWER = 1,
+       PRIME_CHNL_OFFSET_UPPER = 2,
+};
+
+enum rf_type {
+       RF_1T1R = 0,
+       RF_1T2R = 1,
+       RF_2T2R = 2,
+       RF_2T2R_GREEN = 3,
+};
+
+enum ht_channel_width {
+       HT_CHANNEL_WIDTH_20 = 0,
+       HT_CHANNEL_WIDTH_20_40 = 1,
+       HT_CHANNEL_WIDTH_80 = 2,
+};
+
+/* Ref: 802.11i sepc D10.0 7.3.2.25.1
+Cipher Suites Encryption Algorithms */
+enum rt_enc_alg {
+       NO_ENCRYPTION = 0,
+       WEP40_ENCRYPTION = 1,
+       TKIP_ENCRYPTION = 2,
+       RSERVED_ENCRYPTION = 3,
+       AESCCMP_ENCRYPTION = 4,
+       WEP104_ENCRYPTION = 5,
+       AESCMAC_ENCRYPTION = 6, /*IEEE802.11w */
+};
+
+enum rtl_hal_state {
+       _HAL_STATE_STOP = 0,
+       _HAL_STATE_START = 1,
+};
+
+enum rtl_var_map {
+       /*reg map */
+       SYS_ISO_CTRL = 0,
+       SYS_FUNC_EN,
+       SYS_CLK,
+       MAC_RCR_AM,
+       MAC_RCR_AB,
+       MAC_RCR_ACRC32,
+       MAC_RCR_ACF,
+       MAC_RCR_AAP,
+       MAC_HIMR,
+       MAC_HIMRE,
+       MAC_HSISR,
+
+       /*efuse map */
+       EFUSE_TEST,
+       EFUSE_CTRL,
+       EFUSE_CLK,
+       EFUSE_CLK_CTRL,
+       EFUSE_PWC_EV12V,
+       EFUSE_FEN_ELDR,
+       EFUSE_LOADER_CLK_EN,
+       EFUSE_ANA8M,
+       EFUSE_HWSET_MAX_SIZE,
+       EFUSE_MAX_SECTION_MAP,
+       EFUSE_REAL_CONTENT_SIZE,
+       EFUSE_OOB_PROTECT_BYTES_LEN,
+       EFUSE_ACCESS,
+       /*CAM map */
+       RWCAM,
+       WCAMI,
+       RCAMO,
+       CAMDBG,
+       SECR,
+       SEC_CAM_NONE,
+       SEC_CAM_WEP40,
+       SEC_CAM_TKIP,
+       SEC_CAM_AES,
+       SEC_CAM_WEP104,
+
+       /*IMR map */
+       RTL_IMR_BCNDMAINT6,     /*Beacon DMA Interrupt 6 */
+       RTL_IMR_BCNDMAINT5,     /*Beacon DMA Interrupt 5 */
+       RTL_IMR_BCNDMAINT4,     /*Beacon DMA Interrupt 4 */
+       RTL_IMR_BCNDMAINT3,     /*Beacon DMA Interrupt 3 */
+       RTL_IMR_BCNDMAINT2,     /*Beacon DMA Interrupt 2 */
+       RTL_IMR_BCNDMAINT1,     /*Beacon DMA Interrupt 1 */
+       RTL_IMR_BCNDOK8,        /*Beacon Queue DMA OK Interrup 8 */
+       RTL_IMR_BCNDOK7,        /*Beacon Queue DMA OK Interrup 7 */
+       RTL_IMR_BCNDOK6,        /*Beacon Queue DMA OK Interrup 6 */
+       RTL_IMR_BCNDOK5,        /*Beacon Queue DMA OK Interrup 5 */
+       RTL_IMR_BCNDOK4,        /*Beacon Queue DMA OK Interrup 4 */
+       RTL_IMR_BCNDOK3,        /*Beacon Queue DMA OK Interrup 3 */
+       RTL_IMR_BCNDOK2,        /*Beacon Queue DMA OK Interrup 2 */
+       RTL_IMR_BCNDOK1,        /*Beacon Queue DMA OK Interrup 1 */
+       RTL_IMR_TIMEOUT2,       /*Timeout interrupt 2 */
+       RTL_IMR_TIMEOUT1,       /*Timeout interrupt 1 */
+       RTL_IMR_TXFOVW,         /*Transmit FIFO Overflow */
+       RTL_IMR_PSTIMEOUT,      /*Power save time out interrupt */
+       RTL_IMR_BcnInt,         /*Beacon DMA Interrupt 0 */
+       RTL_IMR_RXFOVW,         /*Receive FIFO Overflow */
+       RTL_IMR_RDU,            /*Receive Descriptor Unavailable */
+       RTL_IMR_ATIMEND,        /*For 92C,ATIM Window End Interrupt */
+       RTL_IMR_BDOK,           /*Beacon Queue DMA OK Interrup */
+       RTL_IMR_HIGHDOK,        /*High Queue DMA OK Interrupt */
+       RTL_IMR_COMDOK,         /*Command Queue DMA OK Interrupt*/
+       RTL_IMR_TBDOK,          /*Transmit Beacon OK interrup */
+       RTL_IMR_MGNTDOK,        /*Management Queue DMA OK Interrupt */
+       RTL_IMR_TBDER,          /*For 92C,Transmit Beacon Error Interrupt */
+       RTL_IMR_BKDOK,          /*AC_BK DMA OK Interrupt */
+       RTL_IMR_BEDOK,          /*AC_BE DMA OK Interrupt */
+       RTL_IMR_VIDOK,          /*AC_VI DMA OK Interrupt */
+       RTL_IMR_VODOK,          /*AC_VO DMA Interrupt */
+       RTL_IMR_ROK,            /*Receive DMA OK Interrupt */
+       RTL_IMR_HSISR_IND,  /*HSISR Interrupt*/
+       RTL_IBSS_INT_MASKS,     /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK |
+                                * RTL_IMR_TBDER) */
+       RTL_IMR_C2HCMD,         /*fw interrupt*/
+
+       /*CCK Rates, TxHT = 0 */
+       RTL_RC_CCK_RATE1M,
+       RTL_RC_CCK_RATE2M,
+       RTL_RC_CCK_RATE5_5M,
+       RTL_RC_CCK_RATE11M,
+
+       /*OFDM Rates, TxHT = 0 */
+       RTL_RC_OFDM_RATE6M,
+       RTL_RC_OFDM_RATE9M,
+       RTL_RC_OFDM_RATE12M,
+       RTL_RC_OFDM_RATE18M,
+       RTL_RC_OFDM_RATE24M,
+       RTL_RC_OFDM_RATE36M,
+       RTL_RC_OFDM_RATE48M,
+       RTL_RC_OFDM_RATE54M,
+
+       RTL_RC_HT_RATEMCS7,
+       RTL_RC_HT_RATEMCS15,
+
+       /*keep it last */
+       RTL_VAR_MAP_MAX,
+};
+
+/*Firmware PS mode for control LPS.*/
+enum _fw_ps_mode {
+       FW_PS_ACTIVE_MODE = 0,
+       FW_PS_MIN_MODE = 1,
+       FW_PS_MAX_MODE = 2,
+       FW_PS_DTIM_MODE = 3,
+       FW_PS_VOIP_MODE = 4,
+       FW_PS_UAPSD_WMM_MODE = 5,
+       FW_PS_UAPSD_MODE = 6,
+       FW_PS_IBSS_MODE = 7,
+       FW_PS_WWLAN_MODE = 8,
+       FW_PS_PM_Radio_Off = 9,
+       FW_PS_PM_Card_Disable = 10,
+};
+
+enum rt_psmode {
+       EACTIVE,                /*Active/Continuous access. */
+       EMAXPS,                 /*Max power save mode. */
+       EFASTPS,                /*Fast power save mode. */
+       EAUTOPS,                /*Auto power save mode. */
+};
+
+/*LED related.*/
+enum led_ctl_mode {
+       LED_CTL_POWER_ON = 1,
+       LED_CTL_LINK = 2,
+       LED_CTL_NO_LINK = 3,
+       LED_CTL_TX = 4,
+       LED_CTL_RX = 5,
+       LED_CTL_SITE_SURVEY = 6,
+       LED_CTL_POWER_OFF = 7,
+       LED_CTL_START_TO_LINK = 8,
+       LED_CTL_START_WPS = 9,
+       LED_CTL_STOP_WPS = 10,
+};
+
+enum rtl_led_pin {
+       LED_PIN_GPIO0,
+       LED_PIN_LED0,
+       LED_PIN_LED1,
+       LED_PIN_LED2
+};
+
+/*QoS related.*/
+/*acm implementation method.*/
+enum acm_method {
+       eAcmWay0_SwAndHw = 0,
+       eAcmWay1_HW = 1,
+       eAcmWay2_SW = 2,
+};
+
+enum macphy_mode {
+       SINGLEMAC_SINGLEPHY = 0,
+       DUALMAC_DUALPHY,
+       DUALMAC_SINGLEPHY,
+};
+
+enum band_type {
+       BAND_ON_2_4G = 0,
+       BAND_ON_5G,
+       BAND_ON_BOTH,
+       BANDMAX
+};
+
+/*aci/aifsn Field.
+Ref: WMM spec 2.2.2: WME Parameter Element, p.12.*/
+union aci_aifsn {
+       u8 char_data;
+
+       struct {
+               u8 aifsn:4;
+               u8 acm:1;
+               u8 aci:2;
+               u8 reserved:1;
+       } f;                    /* Field */
+};
+
+/*mlme related.*/
+enum wireless_mode {
+       WIRELESS_MODE_UNKNOWN = 0x00,
+       WIRELESS_MODE_A = 0x01,
+       WIRELESS_MODE_B = 0x02,
+       WIRELESS_MODE_G = 0x04,
+       WIRELESS_MODE_AUTO = 0x08,
+       WIRELESS_MODE_N_24G = 0x10,
+       WIRELESS_MODE_N_5G = 0x20,
+       WIRELESS_MODE_AC_5G = 0x40,
+       WIRELESS_MODE_AC_24G  = 0x80
+};
+
+enum ratr_table_mode {
+       RATR_INX_WIRELESS_NGB = 0,              // BGN 40 Mhz 2SS 1SS
+       RATR_INX_WIRELESS_NG = 1,               // GN or N
+       RATR_INX_WIRELESS_NB = 2,               // BGN 20 Mhz 2SS 1SS  or BN
+       RATR_INX_WIRELESS_N = 3,
+       RATR_INX_WIRELESS_GB = 4,
+       RATR_INX_WIRELESS_G = 5,
+       RATR_INX_WIRELESS_B = 6,
+       RATR_INX_WIRELESS_MC = 7,
+       RATR_INX_WIRELESS_AC_5N = 8,
+       RATR_INX_WIRELESS_AC_24N = 9,
+};
+
+enum rtl_link_state {
+       MAC80211_NOLINK = 0,
+       MAC80211_LINKING = 1,
+       MAC80211_LINKED = 2,
+       MAC80211_LINKED_SCANNING = 3,
+};
+
+enum act_category {
+       ACT_CAT_QOS = 1,
+       ACT_CAT_DLS = 2,
+       ACT_CAT_BA = 3,
+       ACT_CAT_HT = 7,
+       ACT_CAT_WMM = 17,
+};
+
+enum ba_action {
+       ACT_ADDBAREQ = 0,
+       ACT_ADDBARSP = 1,
+       ACT_DELBA = 2,
+};
+
+enum rt_polarity_ctl {
+       RT_POLARITY_LOW_ACT = 0,
+       RT_POLARITY_HIGH_ACT = 1,
+};
+
+
+struct octet_string {
+       u8 *octet;
+       u16 length;
+};
+
+struct rtl_hdr_3addr {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+       u8 addr2[ETH_ALEN];
+       u8 addr3[ETH_ALEN];
+       __le16 seq_ctl;
+       u8 payload[0];
+} __packed;
+
+struct rtl_info_element {
+       u8 id;
+       u8 len;
+       u8 data[0];
+} __packed;
+
+struct rtl_probe_rsp {
+       struct rtl_hdr_3addr header;
+       u32 time_stamp[2];
+       __le16 beacon_interval;
+       __le16 capability;
+       /*SSID, supported rates, FH params, DS params,
+          CF params, IBSS params, TIM (if beacon), RSN */
+       struct rtl_info_element info_element[0];
+} __packed;
+
+/*LED related.*/
+/*ledpin Identify how to implement this SW led.*/
+struct rtl_led {
+       void *hw;
+       enum rtl_led_pin ledpin;
+       bool b_ledon;
+};
+
+struct rtl_led_ctl {
+       bool bled_opendrain;
+       struct rtl_led sw_led0;
+       struct rtl_led sw_led1;
+};
+
+struct rtl_qos_parameters {
+       __le16 cw_min;
+       __le16 cw_max;
+       u8 aifs;
+       u8 flag;
+       __le16 tx_op;
+} __packed;
+
+struct rt_smooth_data {
+       u32 elements[100];      /*array to store values */
+       u32 index;              /*index to current array to store */
+       u32 total_num;          /*num of valid elements */
+       u32 total_val;          /*sum of valid elements */
+};
+
+struct rtl_ht_agg {
+       u16 txq_id;
+       u16 wait_for_ba;
+       u16 start_idx;
+       u64 bitmap;
+       u32 rate_n_flags;
+       u8 agg_state;
+       u8 rx_agg_state;
+};
+
+struct rtl_tid_data {
+       u16 seq_number;
+       struct rtl_ht_agg agg;
+};
+
+struct rssi_sta{
+       long undecorated_smoothed_pwdb;
+};
+
+struct rtl_sta_info {
+       struct list_head list;
+       u8 ratr_index;
+       u8 wireless_mode;
+       u8 mimo_ps;
+       u8 mac_addr[6];
+       struct rtl_tid_data tids[MAX_TID_COUNT];
+
+       /* just used for ap adhoc or mesh*/
+       struct rssi_sta rssi_stat;
+} __packed;
+
+#ifdef VIF_TODO
+struct rtl_vif {
+       unsigned int id;
+       /* struct ieee80211_vif __rcu *vif; */
+       struct ieee80211_vif *vif;
+};
+
+struct rtl_vif_info {
+       struct list_head list;
+       bool active;
+       unsigned int id;
+       struct sk_buff *beacon;
+       bool enable_beacon;
+};
+
+struct vif_priv {
+       struct list_head vif_list;
+
+       /* interface mode settings */
+       unsigned long vif_bitmap;
+       unsigned int vifs;
+       struct rtl_vif vif[MAX_VIRTUAL_MAC];
+
+       /* beaconing */
+       spinlock_t beacon_lock;
+       unsigned int global_pretbtt;
+       unsigned int global_beacon_int;
+       /* struct rtl_vif_info __rcu *beacon_iter; */
+       struct rtl_vif_info *beacon_iter;
+       unsigned int beacon_enabled;
+};
+#endif
+
+struct false_alarm_statistics {
+       u32 cnt_parity_fail;
+       u32 cnt_rate_illegal;
+       u32 cnt_crc8_fail;
+       u32 cnt_mcs_fail;
+       u32 cnt_fast_fsync_fail;
+       u32 cnt_sb_search_fail;
+       u32 cnt_ofdm_fail;
+       u32 cnt_cck_fail;
+       u32 cnt_all;
+       u32 cnt_ofdm_cca;
+       u32 cnt_cck_cca;
+       u32 cnt_cca_all;
+       u32 cnt_bw_usc;
+       u32 cnt_bw_lsc;
+};
+
+struct init_gain {
+       u8 xaagccore1;
+       u8 xbagccore1;
+       u8 xcagccore1;
+       u8 xdagccore1;
+       u8 cca;
+
+};
+
+struct wireless_stats {
+       unsigned long txbytesunicast;
+       unsigned long txbytesmulticast;
+       unsigned long txbytesbroadcast;
+       unsigned long rxbytesunicast;
+
+       long rx_snr_db[4];
+       /*Correct smoothed ss in Dbm, only used
+          in driver to report real power now. */
+       long recv_signal_power;
+       long signal_quality;
+       long last_sigstrength_inpercent;
+
+       u32 rssi_calculate_cnt;
+       u32 pwdb_all_cnt;
+
+       /*Transformed, in dbm. Beautified signal
+          strength for UI, not correct. */
+       long signal_strength;
+
+       u8 rx_rssi_percentage[4];
+       u8 rx_evm_dbm[4];
+       u8 rx_evm_percentage[2];
+
+       u16 rx_cfo_short[4];
+       u16 rx_cfo_tail[4];
+
+       struct rt_smooth_data ui_rssi;
+       struct rt_smooth_data ui_link_quality;
+};
+
+struct rate_adaptive {
+       u8 rate_adaptive_disabled;
+       u8 ratr_state;
+       u16 reserve;
+
+       u32 high_rssi_thresh_for_ra;
+       u32 high2low_rssi_thresh_for_ra;
+       u8 low2high_rssi_thresh_for_ra;
+       u32 low_rssi_thresh_for_ra;
+       u32 upper_rssi_threshold_ratr;
+       u32 middleupper_rssi_threshold_ratr;
+       u32 middle_rssi_threshold_ratr;
+       u32 middlelow_rssi_threshold_ratr;
+       u32 low_rssi_threshold_ratr;
+       u32 ultralow_rssi_threshold_ratr;
+       u32 low_rssi_threshold_ratr_40m;
+       u32 low_rssi_threshold_ratr_20m;
+       u8 ping_rssi_enable;
+       u32 ping_rssi_ratr;
+       u32 ping_rssi_thresh_for_ra;
+       u32 last_ratr;
+       u8 pre_ratr_state;
+       u8 ldpc_thres;
+       bool use_ldpc;
+       bool lower_rts_rate;
+       bool is_special_data;
+};
+
+struct regd_pair_mapping {
+       u16 reg_dmnenum;
+       u16 reg_5ghz_ctl;
+       u16 reg_2ghz_ctl;
+};
+
+struct dynamic_primary_cca{
+       u8 pricca_flag;
+       u8 intf_flag;
+       u8 intf_type;
+       u8 dup_rts_flag;
+       u8 monitor_flag;
+       u8 ch_offset;
+       u8 mf_state;
+};
+
+struct rtl_regulatory {
+       char alpha2[2];
+       u16 country_code;
+       u16 max_power_level;
+       u32 tp_scale;
+       u16 current_rd;
+       u16 current_rd_ext;
+       int16_t power_limit;
+       struct regd_pair_mapping *regpair;
+};
+
+struct rtl_rfkill {
+       bool rfkill_state;      /*0 is off, 1 is on */
+};
+
+/*for P2P PS**/
+#define        P2P_MAX_NOA_NUM         2
+
+enum p2p_role {
+       P2P_ROLE_DISABLE = 0,
+       P2P_ROLE_DEVICE = 1,
+       P2P_ROLE_CLIENT = 2,
+       P2P_ROLE_GO = 3
+};
+
+enum p2p_ps_state {
+       P2P_PS_DISABLE = 0,
+       P2P_PS_ENABLE = 1,
+       P2P_PS_SCAN = 2,
+       P2P_PS_SCAN_DONE = 3,
+       P2P_PS_ALLSTASLEEP = 4, // for P2P GO
+};
+
+enum p2p_ps_mode {
+       P2P_PS_NONE = 0,
+       P2P_PS_CTWINDOW = 1,
+       P2P_PS_NOA = 2,
+       P2P_PS_MIX = 3, // CTWindow and NoA
+};
+
+struct rtl_p2p_ps_info {
+       enum p2p_ps_mode p2p_ps_mode; /* indicate p2p ps mode */
+       enum p2p_ps_state p2p_ps_state; /* indicate p2p ps state */
+       u8 noa_index; /* Identifies and instance of Notice of Absence timing. */
+       /* Client traffic window. A period of time in TU after TBTT. */
+       u8 ctwindow;
+       u8 opp_ps; /* opportunistic power save. */
+       u8 noa_num; /* number of NoA descriptor in P2P IE. */
+       /* Count for owner, Type of client. */
+       u8 noa_count_type[P2P_MAX_NOA_NUM];
+       /* Max duration for owner, preferred or
+        * min acceptable duration for client. */
+       u32 noa_duration[P2P_MAX_NOA_NUM];
+       /* Length of interval for owner, preferred or
+        * max acceptable interval of client. */
+       u32 noa_interval[P2P_MAX_NOA_NUM];
+       /* schedule expressed in terms of the lower 4 bytes of the TSF timer. */
+       u32 noa_start_time[P2P_MAX_NOA_NUM];
+};
+
+ struct p2p_ps_offload_t {
+       u8 Offload_En:1;
+       u8 role:1; /* 1: Owner, 0: Client */
+       u8 CTWindow_En:1;
+       u8 NoA0_En:1;
+       u8 NoA1_En:1;
+       u8 AllStaSleep:1;
+       u8 discovery:1;
+       u8 reserved:1;
+};
+
+#define IQK_MATRIX_REG_NUM     8
+#define IQK_MATRIX_SETTINGS_NUM         (14+24+21) // Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G
+struct iqk_matrix_regs {
+       bool b_iqk_done;
+       long value[1][IQK_MATRIX_REG_NUM];
+};
+
+struct rtl_phy {
+       struct bb_reg_def phyreg_def[4];        /*Radio A/B/C/D */
+       struct init_gain initgain_backup;
+       enum io_type current_io_type;
+
+       u8 rf_mode;
+       u8 rf_type;
+       u8 current_chan_bw;
+       u8 set_bwmode_inprogress;
+       u8 sw_chnl_inprogress;
+       u8 sw_chnl_stage;
+       u8 sw_chnl_step;
+       u8 current_channel;
+       u8 h2c_box_num;
+       u8 set_io_inprogress;
+       u8 lck_inprogress;
+
+       /* record for power tracking */
+       s32 reg_e94;
+       s32 reg_e9c;
+       s32 reg_ea4;
+       s32 reg_eac;
+       s32 reg_eb4;
+       s32 reg_ebc;
+       s32 reg_ec4;
+       s32 reg_ecc;
+       u8 rfpienable;
+       u8 reserve_0;
+       u16 reserve_1;
+       u32 reg_c04, reg_c08, reg_874;
+       u32 adda_backup[16];
+       u32 iqk_mac_backup[IQK_MAC_REG_NUM];
+       u32 iqk_bb_backup[10];
+       bool iqk_initialized;
+
+       bool rfpath_rx_enable[MAX_RF_PATH];
+       /*Jaguar*/
+       u8 reg_837;
+       /* Dul mac */
+       bool b_need_iqk;
+       struct iqk_matrix_regs iqk_matrix_regsetting[IQK_MATRIX_SETTINGS_NUM];
+
+       bool b_rfpi_enable;
+
+       bool b_iqk_in_progress;
+
+       u8 pwrgroup_cnt;
+       u8 bcck_high_power;
+       /* this is for 88E & 8723A */
+       u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16];
+       /* this is for 92EE */
+       u32 tx_power_by_rate_offset[TX_PWR_BY_RATE_NUM_BAND]
+                                  [TX_PWR_BY_RATE_NUM_RF]
+                                  [TX_PWR_BY_RATE_NUM_RF]
+                                  [TX_PWR_BY_RATE_NUM_SECTION];
+       u8 txpwr_by_rate_base_24g[TX_PWR_BY_RATE_NUM_RF]
+                                [TX_PWR_BY_RATE_NUM_RF]
+                                [MAX_BASE_NUM_IN_PHY_REG_PG_24G];
+
+       u8 txpwr_by_rate_base_5g[TX_PWR_BY_RATE_NUM_RF]
+                               [TX_PWR_BY_RATE_NUM_RF]
+                               [MAX_BASE_NUM_IN_PHY_REG_PG_5G];
+       u8 default_initialgain[4];
+
+       /* the current Tx power level */
+       u8 cur_cck_txpwridx;
+       u8 cur_ofdm24g_txpwridx;
+       u8 cur_bw20_txpwridx;
+       u8 cur_bw40_txpwridx;
+
+       u32 rfreg_chnlval[2];
+       bool b_apk_done;
+       u32 reg_rf3c[2];        /* pathA / pathB  */
+
+       u32 backup_rf_0x1a;/*92ee*/
+       /* bfsync */
+       u8 framesync;
+       u32 framesync_c34;
+
+       u8 num_total_rfpath;
+       u16 rf_pathmap;
+
+       u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/
+
+       enum rt_polarity_ctl polarity_ctl;
+};
+
+#define RTL_AGG_STOP                                           0
+#define RTL_AGG_PROGRESS                                       1
+#define RTL_AGG_START                                          2
+#define RTL_AGG_OPERATIONAL                                    3
+#define RTL_RX_AGG_START                                       1
+#define RTL_RX_AGG_STOP                                        0
+
+struct rtl_priv;
+struct rtl_io {
+       struct device *dev;
+
+       /*PCI MEM map */
+       unsigned long pci_mem_end;      /*shared mem end        */
+       unsigned long pci_mem_start;    /*shared mem start */
+
+       /*PCI IO map */
+       unsigned long pci_base_addr;    /*device I/O address */
+
+       void (*write8_async) (struct rtl_priv * rtlpriv, u32 addr, u8 val);
+       void (*write16_async) (struct rtl_priv * rtlpriv, u32 addr, u16 val);
+       void (*write32_async) (struct rtl_priv * rtlpriv, u32 addr, u32 val);
+
+       u8(*read8_sync) (struct rtl_priv * rtlpriv, u32 addr);
+       u16(*read16_sync) (struct rtl_priv * rtlpriv, u32 addr);
+       u32(*read32_sync) (struct rtl_priv * rtlpriv, u32 addr);
+
+};
+
+struct rtl_mac {
+       u8 mac_addr[ETH_ALEN];
+       u8 mac80211_registered;
+       u8 beacon_enabled;
+
+       u32 tx_ss_num;
+       u32 rx_ss_num;
+
+       struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
+       struct ieee80211_hw *hw;
+       struct ieee80211_vif *vif;
+       enum nl80211_iftype opmode;
+
+       /*Probe Beacon management */
+       enum rtl_link_state link_state;
+
+       int n_channels;
+       int n_bitrates;
+
+       bool offchan_deley;
+       u8 p2p; /*using p2p role*/
+       bool p2p_in_use;
+
+       /*filters */
+       u32 rx_conf;
+
+       bool act_scanning;
+       u8 cnt_after_linked;
+       bool skip_scan;
+
+       /* early mode */
+       /* skb wait queue */
+       struct sk_buff_head skb_waitq[MAX_TID_COUNT];
+
+       /*RDG*/
+       bool rdg_en;
+
+       /*AP*/
+       u8 bssid[6];
+       u32 vendor;
+       u32 basic_rates; /* b/g rates */
+       u8 ht_enable;
+       u8 bw_40;
+       u8 mode;                /* wireless mode */
+       u8 slot_time;
+       u8 short_preamble;
+       u8 use_cts_protect;
+       u8 cur_40_prime_sc;
+       u8 cur_40_prime_sc_bk;
+       u8 cur_80_prime_sc;
+       u64 tsf;
+       u8 retry_short;
+       u8 retry_long;
+       u16 assoc_id;
+       bool bhiddenssid;
+
+       /*IBSS*/
+       int beacon_interval;
+
+       /*AMPDU*/
+       u8 min_space_cfg;       /*For Min spacing configurations */
+       u8 max_mss_density;
+       u8 current_ampdu_factor;
+       u8 current_ampdu_density;
+
+       /*QOS & EDCA */
+       struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE];
+       struct rtl_qos_parameters ac[AC_MAX];
+};
+
+struct rtl_hal {
+       struct ieee80211_hw *hw;
+
+       bool driver_is_goingto_unload;
+       bool up_first_time;
+       bool bfirst_init;
+       bool being_init_adapter;
+       bool b_bbrf_ready;
+       bool b_mac_func_enable;
+       bool b_pre_edcca_enable;
+
+       enum intf_type interface;
+       u16 hw_type;            /*92c or 92d or 92s and so on */
+       u8 ic_class;
+       u8 oem_id;
+       u32 version;            /*version of chip */
+       u8 state;               /*stop 0, start 1 */
+       u8 boad_type;
+
+       /*firmware */
+       u32 fwsize;
+       u8 *pfirmware;
+       u16 fw_version;
+       u16 fw_subversion;
+       bool b_h2c_setinprogress;
+       u8 last_hmeboxnum;
+       bool bfw_ready;
+
+       /*Reserve page start offset except beacon in TxQ. */
+       u8 fw_rsvdpage_startoffset;
+       u8 h2c_txcmd_seq;
+       u8 current_ra_rate;
+
+       /* FW Cmd IO related */
+       u16 fwcmd_iomap;
+       u32 fwcmd_ioparam;
+       bool set_fwcmd_inprogress;
+       u8 current_fwcmd_io;
+
+       bool bfw_clk_change_in_progress;
+       bool ballow_sw_to_change_hwclc;
+       u8 fw_ps_state;
+        struct p2p_ps_offload_t p2p_ps_offload;
+       /**/
+       bool driver_going2unload;
+
+       /*AMPDU init min space*/
+       u8 minspace_cfg;        /*For Min spacing configurations */
+
+       /* Dul mac */
+       enum macphy_mode macphymode;
+       enum band_type current_bandtype;        /* 0:2.4G, 1:5G */
+       enum band_type current_bandtypebackup;
+       enum band_type bandset;
+       /* dual MAC 0--Mac0 1--Mac1 */
+       u32 interfaceindex;
+       /* just for DulMac S3S4 */
+       u8 macphyctl_reg;
+       bool b_earlymode_enable;
+       u8 max_earlymode_num;
+       /* Dul mac*/
+       bool during_mac0init_radiob;
+       bool during_mac1init_radioa;
+       bool reloadtxpowerindex;
+       /* True if IMR or IQK  have done
+       for 2.4G in scan progress */
+       bool b_load_imrandiqk_setting_for2g;
+
+       bool disable_amsdu_8k;
+       bool bmaster_of_dmsp;
+       bool bslave_of_dmsp;
+
+       u16 rx_tag;/*for 92ee*/
+       u8 rts_en;
+};
+
+struct rtl_security {
+       /*default 0 */
+       bool use_sw_sec;
+
+       bool being_setkey;
+       bool use_defaultkey;
+       /*Encryption Algorithm for Unicast Packet */
+       enum rt_enc_alg pairwise_enc_algorithm;
+       /*Encryption Algorithm for Brocast/Multicast */
+       enum rt_enc_alg group_enc_algorithm;
+       /*Cam Entry Bitmap */
+       u32 hwsec_cam_bitmap;
+       u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN];
+       /*local Key buffer, indx 0 is for
+          pairwise key 1-4 is for agoup key. */
+       u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN];
+       u8 key_len[KEY_BUF_SIZE];
+
+       /*The pointer of Pairwise Key,
+          it always points to KeyBuf[4] */
+       u8 *pairwise_key;
+};
+
+struct rtl_dig {
+       u8 dig_enable_flag;
+       u8 dig_ext_port_stage;
+
+       u32 rssi_lowthresh;
+       u32 rssi_highthresh;
+
+       u32 fa_lowthresh;
+       u32 fa_highthresh;
+
+       u8 cursta_connectstate;
+       u8 presta_connectstate;
+       u8 curmultista_connectstate;
+
+       u8 pre_igvalue;
+       u8 cur_igvalue;
+
+       char backoff_val;
+       char backoff_val_range_max;
+       char backoff_val_range_min;
+       u8 rx_gain_range_max;
+       u8 rx_gain_range_min;
+       u8 rssi_val_min;
+       u8 min_undecorated_pwdb_for_dm;
+       long last_min_undecorated_pwdb_for_dm;
+
+       u8 pre_cck_pd_state;
+       u8 cur_cck_pd_state;
+
+       u8 large_fa_hit;
+       u8 forbidden_igi;
+       u32 recover_cnt;
+
+};
+
+struct rtl_pstbl {
+       u8 pre_ccastate;
+       u8 cur_ccasate;
+
+       u8 pre_rfstate;
+       u8 cur_rfstate;
+
+       long rssi_val_min;
+
+};
+
+#define ASSOCIATE_ENTRY_NUM    32+1
+
+struct fast_ant_trainning{
+       u8 bssid[6];
+       u8 antsel_rx_keep_0;
+       u8 antsel_rx_keep_1;
+       u8 antsel_rx_keep_2;
+       u32 ant_sum_rssi[7];
+       u32 ant_rssi_cnt[7];
+       u32 ant_ave_rssi[7];
+       u8 fat_state;
+       u32 train_idx;
+       u8 antsel_a[ASSOCIATE_ENTRY_NUM];
+       u8 antsel_b[ASSOCIATE_ENTRY_NUM];
+       u8 antsel_c[ASSOCIATE_ENTRY_NUM];
+       u32 main_ant_sum[ASSOCIATE_ENTRY_NUM];
+       u32 aux_ant_sum[ASSOCIATE_ENTRY_NUM];
+       u32 main_ant_cnt[ASSOCIATE_ENTRY_NUM];
+       u32 aux_ant_cnt[ASSOCIATE_ENTRY_NUM];
+       u8 rx_idle_ant;
+       bool b_becomelinked;
+};
+
+struct dm_phy_dbg_info {
+       char rx_snrdb[4];
+       u64 num_qry_phy_status;
+       u64 num_qry_phy_status_cck;
+       u64 num_qry_phy_status_ofdm;
+       u16 num_qry_beacon_pkt;
+       u16 num_non_be_pkt;
+       s32 rx_evm[4];
+};
+
+struct rtl_dm {
+       /*PHY status for DM */
+       long entry_min_undecoratedsmoothed_pwdb;
+       long undecorated_smoothed_pwdb; /*out dm */
+       long entry_max_undecoratedsmoothed_pwdb;
+       bool b_dm_initialgain_enable;
+       bool bdynamic_txpower_enable;
+       bool bcurrent_turbo_edca;
+       bool bis_any_nonbepkts; /*out dm */
+       bool bis_cur_rdlstate;
+       bool btxpower_trackinginit;
+       bool b_disable_framebursting;
+       bool b_cck_inch14;
+       bool btxpower_tracking;
+       bool b_useramask;
+       bool brfpath_rxenable[4];
+       bool binform_fw_driverctrldm;
+       bool bcurrent_mrc_switch;
+       u8 txpowercount;
+
+       u8 thermalvalue_rxgain;
+       u8 thermalvalue_iqk;
+       u8 thermalvalue_lck;
+       u8 thermalvalue;
+       u8 thermalvalue_avg[AVG_THERMAL_NUM];
+       u8 thermalvalue_avg_index;
+       bool bdone_txpower;
+       u8 last_dtp_lvl;
+       u8 dynamic_txhighpower_lvl;     /*Tx high power level */
+       u8 dm_flag;     /*Indicate if each dynamic mechanism's status. */
+       u8 dm_type;
+       u8 txpower_track_control;
+       bool binterrupt_migration;
+       bool bdisable_tx_int;
+       char ofdm_index[MAX_RF_PATH];
+       u8 default_ofdm_index;
+       u8 default_cck_index;
+       char cck_index;
+       char delta_power_index[MAX_RF_PATH];
+       char delta_power_index_last[MAX_RF_PATH];
+       char power_index_offset[MAX_RF_PATH];
+       char aboslute_ofdm_swing_idx[MAX_RF_PATH];
+       char remnant_ofdm_swing_idx[MAX_RF_PATH];
+       char remnant_cck_idx;
+       bool modify_txagc_flag_path_a;
+       bool modify_txagc_flag_path_b;
+
+       bool b_one_entry_only;
+       struct dm_phy_dbg_info dbginfo;
+       /* Dynamic ATC switch */
+
+       bool atc_status;
+       bool large_cfo_hit;
+       bool is_freeze;
+       int cfo_tail[2];
+       int cfo_ave_pre;
+       int crystal_cap;
+       u8 cfo_threshold;
+       u32 packet_count;
+       u32 packet_count_pre;
+       u8 tx_rate;
+
+
+       /*88e tx power tracking*/
+       u8 bb_swing_idx_ofdm[2];
+       u8 bb_swing_idx_ofdm_current;
+       u8 bb_swing_idx_ofdm_base[MAX_RF_PATH];
+       bool bb_swing_flag_Ofdm;
+       u8 bb_swing_idx_cck;
+       u8 bb_swing_idx_cck_current;
+       u8 bb_swing_idx_cck_base;
+       bool bb_swing_flag_cck;
+
+       char bb_swing_diff_2g;
+       char bb_swing_diff_5g;
+
+       u8 delta_swing_table_idx_24gccka_p[DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_24gccka_n[DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_24gcckb_p[DELTA_SWINGIDX_SIZE];
+       u8 delta_swing_table_idx_24gcckb_n[DELTA_SWINGIDX_SIZE];
+       u8 delta_swing_table_idx_24ga_p[DELTA_SWINGIDX_SIZE];
+       u8 delta_swing_table_idx_24ga_n[DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_24gb_p[DELTA_SWINGIDX_SIZE];
+       u8 delta_swing_table_idx_24gb_n[DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_5ga_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_5ga_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_5gb_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_5gb_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_24ga_p_8188e[DELTA_SWINGIDX_SIZE];
+    u8 delta_swing_table_idx_24ga_n_8188e[DELTA_SWINGIDX_SIZE];
+
+
+       /* DMSP */
+       bool supp_phymode_switch;
+
+       /* DulMac */
+       struct rtl_dig dm_digtable;
+       struct rtl_pstbl dm_pstable;
+       struct fast_ant_trainning fat_table;
+
+       u8      resp_tx_path;
+       u8      path_sel;
+       u32     patha_sum;
+       u32     pathb_sum;
+       u32     patha_cnt;
+       u32     pathb_cnt;
+
+       u8 pre_channel;
+       u8 *p_channel;
+       u8 linked_interval;
+
+       u64 last_tx_ok_cnt;
+       u64 last_rx_ok_cnt;
+};
+
+#define        EFUSE_MAX_LOGICAL_SIZE          256
+
+struct rtl_efuse {
+       bool bautoLoad_ok;
+       bool bootfromefuse;
+       u16 max_physical_size;
+
+       u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE];
+       u16 efuse_usedbytes;
+       u8 efuse_usedpercentage;
+#ifdef EFUSE_REPG_WORKAROUND
+       bool efuse_re_pg_sec1flag;
+       u8 efuse_re_pg_data[8];
+#endif
+
+       u8 autoload_failflag;
+       u8 autoload_status;
+
+       short epromtype;
+       u16 eeprom_vid;
+       u16 eeprom_did;
+       u16 eeprom_svid;
+       u16 eeprom_smid;
+       u8 eeprom_oemid;
+       u16 eeprom_channelplan;
+       u8 eeprom_version;
+
+       u8 dev_addr[6];
+       u8 board_type;
+       u8 wowlan_enable;
+       u8 antenna_div_cfg;
+       u8 antenna_div_type;
+
+       bool b_txpwr_fromeprom;
+       u8 eeprom_crystalcap;
+       u8 eeprom_tssi[2];
+       u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */
+       u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX];
+       u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX];
+       u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G];
+       u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX];
+       u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][CHANNEL_GROUP_MAX];
+
+
+       u8 internal_pa_5g[2];   /* pathA / pathB */
+       u8 eeprom_c9;
+       u8 eeprom_cc;
+
+       /*For power group */
+       u8 eeprom_pwrgroup[2][3];
+       u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER];
+       u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER];
+
+       u8 txpwrlevel_cck[MAX_RF_PATH][CHANNEL_MAX_NUMBER_2G];
+       /*For HT 40MHZ pwr */
+       u8 txpwrlevel_ht40_1s[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+       /*For HT 40MHZ pwr */
+       u8 txpwrlevel_ht40_2s[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+       char txpwr_cckdiff[MAX_RF_PATH][MAX_TX_COUNT]; /*CCK_24G_Diff*/
+       /*HT 20<->40 Pwr diff */
+       char txpwr_ht20diff[MAX_RF_PATH][MAX_TX_COUNT]; /*BW20_24G_Diff*/
+       char txpwr_ht40diff[MAX_RF_PATH][MAX_TX_COUNT];/*BW40_24G_Diff*/
+       /*For HT<->legacy pwr diff */
+       char txpwr_legacyhtdiff[MAX_RF_PATH][MAX_TX_COUNT];/*OFDM_24G_Diff*/
+
+       u8 txpwr_5g_bw40base[MAX_RF_PATH][CHANNEL_MAX_NUMBER];
+       u8 txpwr_5g_bw80base[MAX_RF_PATH][CHANNEL_MAX_NUMBER_5G_80M];
+       char txpwr_5g_ofdmdiff[MAX_RF_PATH][MAX_TX_COUNT];
+       char txpwr_5g_bw20diff[MAX_RF_PATH][MAX_TX_COUNT];
+       char txpwr_5g_bw40diff[MAX_RF_PATH][MAX_TX_COUNT];
+       char txpwr_5g_bw80diff[MAX_RF_PATH][MAX_TX_COUNT];
+
+       u8 txpwr_safetyflag;            /* Band edge enable flag */
+       u16 eeprom_txpowerdiff;
+       u8 legacy_httxpowerdiff;        /* Legacy to HT rate power diff */
+       u8 antenna_txpwdiff[3];
+
+       u8 eeprom_regulatory;
+       u8 eeprom_thermalmeter;
+       u8 thermalmeter[2];/*ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 */
+       u16 tssi_13dbm;
+       u8 crystalcap;          /* CrystalCap. */
+       u8 delta_iqk;
+       u8 delta_lck;
+
+       u8 legacy_ht_txpowerdiff;       /*Legacy to HT rate power diff */
+       bool b_apk_thermalmeterignore;
+
+       bool b1x1_recvcombine;
+       bool b1ss_support;
+
+       /*channel plan */
+       u8 channel_plan;
+};
+
+struct rtl_ps_ctl {
+       bool pwrdomain_protect;
+       bool b_in_powersavemode;
+       bool rfchange_inprogress;
+       bool b_swrf_processing;
+       bool b_hwradiooff;
+       /*
+        * just for PCIE ASPM
+        * If it supports ASPM, Offset[560h] = 0x40,
+        * otherwise Offset[560h] = 0x00.
+        * */
+       bool b_support_aspm;
+       bool b_support_backdoor;
+
+       /*for LPS */
+       enum rt_psmode dot11_psmode;    /*Power save mode configured. */
+       bool b_swctrl_lps;
+       bool b_fwctrl_lps;
+       u8 fwctrl_psmode;
+       /*For Fw control LPS mode */
+       u8 b_reg_fwctrl_lps;
+       /*Record Fw PS mode status. */
+       bool b_fw_current_inpsmode;
+       u8 reg_max_lps_awakeintvl;
+       bool report_linked;
+       bool b_low_power_enable;/*for 32k*/
+
+       /*for IPS */
+       bool b_inactiveps;
+
+       u32 rfoff_reason;
+
+       /*RF OFF Level */
+       u32 cur_ps_level;
+       u32 reg_rfps_level;
+
+       /*just for PCIE ASPM */
+       u8 const_amdpci_aspm;
+
+       enum rf_pwrstate inactive_pwrstate;
+       enum rf_pwrstate rfpwr_state;   /*cur power state */
+
+       /* for SW LPS*/
+       bool sw_ps_enabled;
+       bool state;
+       bool state_inap;
+       bool multi_buffered;
+       u16 nullfunc_seq;
+       unsigned int dtim_counter;
+       unsigned int sleep_ms;
+       unsigned long last_sleep_jiffies;
+       unsigned long last_awake_jiffies;
+       unsigned long last_delaylps_stamp_jiffies;
+       unsigned long last_dtim;
+       unsigned long last_beacon;
+       unsigned long last_action;
+       unsigned long last_slept;
+
+       /*For P2P PS */
+       struct rtl_p2p_ps_info p2p_ps_info;
+       u8 pwr_mode;
+       u8 smart_ps;
+};
+
+struct rtl_stats {
+       u8 psaddr[ETH_ALEN];
+       u32 mac_time[2];
+       s8 rssi;
+       u8 signal;
+       u8 noise;
+       u8 rate;                /* hw desc rate */
+       u8 rawdata;
+       u8 received_channel;
+       u8 control;
+       u8 mask;
+       u8 freq;
+       u16 len;
+       u64 tsf;
+       u32 beacon_time;
+       u8 nic_type;
+       u16 length;
+       u8 signalquality;       /*in 0-100 index. */
+       /*
+        * Real power in dBm for this packet,
+        * no beautification and aggregation.
+        * */
+       s32 recvsignalpower;
+       s8 rxpower;             /*in dBm Translate from PWdB */
+       u8 signalstrength;      /*in 0-100 index. */
+       u16 b_hwerror:1;
+       u16 b_crc:1;
+       u16 b_icv:1;
+       u16 b_shortpreamble:1;
+       u16 antenna:1;
+       u16 decrypted:1;
+       u16 wakeup:1;
+       u32 timestamp_low;
+       u32 timestamp_high;
+       bool b_shift;
+
+       u8 rx_drvinfo_size;
+       u8 rx_bufshift;
+       bool b_isampdu;
+       bool b_isfirst_ampdu;
+       bool rx_is40Mhzpacket;
+       u32 rx_pwdb_all;
+       u8 rx_mimo_signalstrength[4];   /*in 0~100 index */
+       s8 rx_mimo_signalquality[4];
+       u8 rx_mimo_evm_dbm[4];
+       u16 cfo_short[4];               /* per-path's Cfo_short */
+       u16 cfo_tail[4];
+
+       u8 rx_pwr[4]; /* per-path's pwdb */
+       u8 rx_snr[4]; /* per-path's SNR */
+       u8 bandwidth;
+       u8 bt_coex_pwr_adjust;
+       bool b_packet_matchbssid;
+       bool b_is_cck;
+       bool b_is_ht;
+       bool b_packet_toself;
+       bool b_packet_beacon;   /*for rssi */
+       char cck_adc_pwdb[4];   /*for rx path selection */
+
+       u8 packet_report_type;
+
+       u32 macid;
+       u8 wake_match;
+       u32 bt_rx_rssi_percentage;
+       u32 macid_valid_entry[2];
+};
+
+struct rt_link_detect {
+       /* count for raoming */
+       u32 bcn_rx_inperiod;
+       u32 roam_times;
+
+       u32 num_tx_in4period[4];
+       u32 num_rx_in4period[4];
+
+       u32 num_tx_inperiod;
+       u32 num_rx_inperiod;
+
+       bool b_busytraffic;
+       bool b_tx_busy_traffic;
+       bool b_rx_busy_traffic;
+       bool b_higher_busytraffic;
+       bool b_higher_busyrxtraffic;
+
+       u32 tidtx_in4period[MAX_TID_COUNT][4];
+       u32 tidtx_inperiod[MAX_TID_COUNT];
+       bool higher_busytxtraffic[MAX_TID_COUNT];
+};
+
+struct rtl_tcb_desc {
+       u8 b_packet_bw:1;
+       u8 b_multicast:1;
+       u8 b_broadcast:1;
+
+       u8 b_rts_stbc:1;
+       u8 b_rts_enable:1;
+       u8 b_cts_enable:1;
+       u8 b_rts_use_shortpreamble:1;
+       u8 b_rts_use_shortgi:1;
+       u8 rts_sc:1;
+       u8 b_rts_bw:1;
+       u8 rts_rate;
+
+       u8 use_shortgi:1;
+       u8 use_shortpreamble:1;
+       u8 use_driver_rate:1;
+       u8 disable_ratefallback:1;
+
+       u8 ratr_index;
+       u8 mac_id;
+       u8 hw_rate;
+
+       u8 b_last_inipkt:1;
+       u8 b_cmd_or_init:1;
+       u8 queue_index;
+
+       /* early mode */
+       u8 empkt_num;
+       /* The max value by HW */
+       u32 empkt_len[10];
+       bool btx_enable_sw_calc_duration;
+       /* used for hal construct pkt,
+        * we may set desc when tx */
+       u8 self_desc;
+};
+
+struct proxim {
+       bool proxim_on;
+
+       void *proximity_priv;
+       int (*proxim_rx)(struct ieee80211_hw *hw, struct rtl_stats *status,
+                        struct sk_buff *skb);
+       u8  (*proxim_get_var)(struct ieee80211_hw *hw, u8 type);
+};
+
+struct rtl_hal_ops {
+       int (*init_sw_vars) (struct ieee80211_hw * hw);
+       void (*deinit_sw_vars) (struct ieee80211_hw * hw);
+       void (*read_eeprom_info) (struct ieee80211_hw * hw);
+       void (*interrupt_recognized) (struct ieee80211_hw * hw,
+                                     u32 * p_inta, u32 * p_intb);
+       int (*hw_init) (struct ieee80211_hw * hw);
+       void (*hw_disable) (struct ieee80211_hw * hw);
+       void (*hw_suspend) (struct ieee80211_hw * hw);
+       void (*hw_resume) (struct ieee80211_hw * hw);
+       void (*enable_interrupt) (struct ieee80211_hw * hw);
+       void (*disable_interrupt) (struct ieee80211_hw * hw);
+       int (*set_network_type) (struct ieee80211_hw * hw,
+                                enum nl80211_iftype type);
+       void (*set_chk_bssid)(struct ieee80211_hw *hw,
+                             bool check_bssid);
+       void (*set_bw_mode) (struct ieee80211_hw * hw,
+                            enum nl80211_channel_type ch_type);
+        u8(*switch_channel) (struct ieee80211_hw * hw);
+       void (*set_qos) (struct ieee80211_hw * hw, int aci);
+       void (*set_bcn_reg) (struct ieee80211_hw * hw);
+       void (*set_bcn_intv) (struct ieee80211_hw * hw);
+       void (*update_interrupt_mask) (struct ieee80211_hw * hw,
+                                      u32 add_msr, u32 rm_msr);
+       void (*get_hw_reg) (struct ieee80211_hw * hw, u8 variable, u8 * val);
+       void (*set_hw_reg) (struct ieee80211_hw * hw, u8 variable, u8 * val);
+       void (*update_rate_tbl) (struct ieee80211_hw * hw,
+                                struct ieee80211_sta *sta, u8 rssi_level);
+       void (*pre_fill_tx_bd_desc) (struct ieee80211_hw *hw, u8 *tx_bd_desc,
+                                    u8 *desc, u8 queue_index,
+                                    struct sk_buff *skb, dma_addr_t addr);
+       u16 (*rx_desc_buff_remained_cnt) (struct ieee80211_hw *hw,
+                                         u8 queue_index);
+       void (*rx_check_dma_ok) (struct ieee80211_hw *hw, u8 *header_desc,
+                                u8 queue_index);
+       void (*fill_tx_desc) (struct ieee80211_hw * hw,
+                             struct ieee80211_hdr * hdr,
+                             u8 * pdesc_tx, u8 * pbd_desc,
+                             struct ieee80211_tx_info * info,
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
+/*<delete in kernel end>*/
+                             struct ieee80211_sta *sta,
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+                             struct sk_buff * skb, u8 hw_queue,
+                             struct rtl_tcb_desc *ptcb_desc);
+       void (*fill_tx_cmddesc) (struct ieee80211_hw * hw, u8 * pdesc,
+                                bool b_firstseg, bool b_lastseg,
+                                struct sk_buff * skb);
+        bool(*query_rx_desc) (struct ieee80211_hw * hw,
+                              struct rtl_stats * status,
+                              struct ieee80211_rx_status * rx_status,
+                              u8 * pdesc, struct sk_buff * skb);
+       void (*set_channel_access) (struct ieee80211_hw * hw);
+        bool(*radio_onoff_checking) (struct ieee80211_hw * hw, u8 * valid);
+       void (*dm_watchdog) (struct ieee80211_hw * hw);
+       void (*scan_operation_backup) (struct ieee80211_hw * hw, u8 operation);
+        bool(*set_rf_power_state) (struct ieee80211_hw * hw,
+                                   enum rf_pwrstate rfpwr_state);
+       void (*led_control) (struct ieee80211_hw * hw,
+                            enum led_ctl_mode ledaction);
+       void (*set_desc) (struct ieee80211_hw *hw, u8 * pdesc, bool istx,
+                         u8 desc_name, u8 * val);
+        u32(*get_desc) (u8 * pdesc, bool istx, u8 desc_name);
+       bool (*is_tx_desc_closed) (struct ieee80211_hw *hw,
+                                  u8 hw_queue, u16 index);
+       void (*tx_polling) (struct ieee80211_hw * hw, u8 hw_queue);
+       void (*enable_hw_sec) (struct ieee80211_hw * hw);
+       void (*set_key) (struct ieee80211_hw * hw, u32 key_index,
+                        u8 * p_macaddr, bool is_group, u8 enc_algo,
+                        bool is_wepkey, bool clear_all);
+       void (*init_sw_leds) (struct ieee80211_hw * hw);
+        u32(*get_bbreg) (struct ieee80211_hw * hw, u32 regaddr, u32 bitmask);
+       void (*set_bbreg) (struct ieee80211_hw * hw, u32 regaddr, u32 bitmask,
+                          u32 data);
+        u32(*get_rfreg) (struct ieee80211_hw * hw, enum radio_path rfpath,
+                         u32 regaddr, u32 bitmask);
+       void (*set_rfreg) (struct ieee80211_hw * hw, enum radio_path rfpath,
+                          u32 regaddr, u32 bitmask, u32 data);
+       void (*allow_all_destaddr)(struct ieee80211_hw *hw,
+               bool allow_all_da, bool write_into_reg);
+       void (*linked_set_reg) (struct ieee80211_hw * hw);
+       void (*check_switch_to_dmdp) (struct ieee80211_hw * hw);
+       void (*dualmac_easy_concurrent) (struct ieee80211_hw *hw);
+       void (*dualmac_switch_to_dmdp) (struct ieee80211_hw *hw);
+       void (*c2h_command_handle) (struct ieee80211_hw *hw);
+       void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, bool mstate);
+       void (*bt_turn_off_bt_coexist_before_enter_lps) (struct ieee80211_hw *hw);
+       void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,
+                             u32 cmd_len, u8 *p_cmdbuffer);
+       bool (*get_btc_status) (void);
+       u32 (*rx_command_packet_handler)(struct ieee80211_hw *hw, struct rtl_stats status, struct sk_buff *skb);
+};
+
+struct rtl_intf_ops {
+       /*com */
+       void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
+       int (*adapter_start) (struct ieee80211_hw * hw);
+       void (*adapter_stop) (struct ieee80211_hw * hw);
+       bool (*check_buddy_priv)(struct ieee80211_hw *hw,
+                       struct rtl_priv **buddy_priv);
+
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+       int (*adapter_tx) (struct ieee80211_hw * hw, struct sk_buff * skb,
+                          struct rtl_tcb_desc *ptcb_desc);
+#else
+/*<delete in kernel end>*/
+       int (*adapter_tx) (struct ieee80211_hw *hw,
+                          struct ieee80211_sta *sta,
+                          struct sk_buff *skb,
+                          struct rtl_tcb_desc *ptcb_desc);
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+       void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
+#else
+       void (*flush)(struct ieee80211_hw *hw, bool drop);
+#endif
+       int (*reset_trx_ring) (struct ieee80211_hw * hw);
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+       bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb);
+#else
+/*<delete in kernel end>*/
+       bool (*waitq_insert) (struct ieee80211_hw *hw,
+                             struct ieee80211_sta *sta,
+                             struct sk_buff *skb);
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+
+       /*pci */
+       void (*disable_aspm) (struct ieee80211_hw * hw);
+       void (*enable_aspm) (struct ieee80211_hw * hw);
+
+       /*usb */
+};
+
+struct rtl_mod_params {
+       /* default: 0 = using hardware encryption */
+       bool sw_crypto;
+
+       /* default: 1 = using no linked power save */
+       bool b_inactiveps;
+
+       /* default: 1 = using linked sw power save */
+       bool b_swctrl_lps;
+
+       /* default: 1 = using linked fw power save */
+       bool b_fwctrl_lps;
+};
+
+struct rtl_hal_cfg {
+       u8 bar_id;
+       bool write_readback;
+       char *name;
+       char *fw_name;
+       struct rtl_hal_ops *ops;
+       struct rtl_mod_params *mod_params;
+
+       /*this map used for some registers or vars
+          defined int HAL but used in MAIN */
+       u32 maps[RTL_VAR_MAP_MAX];
+
+};
+
+struct rtl_locks {
+       /* mutex */
+       struct mutex conf_mutex;
+
+       /*spin lock */
+       spinlock_t ips_lock;
+       spinlock_t irq_th_lock;
+       spinlock_t h2c_lock;
+       spinlock_t rf_ps_lock;
+       spinlock_t rf_lock;
+       spinlock_t lps_lock;
+       spinlock_t waitq_lock;
+       spinlock_t entry_list_lock;
+
+       /*FW clock change */
+       spinlock_t fw_ps_lock;
+
+       /*Dul mac*/
+       spinlock_t cck_and_rw_pagea_lock;
+
+       /*Easy concurrent*/
+       spinlock_t check_sendpkt_lock;
+
+       spinlock_t iqk_lock;
+};
+
+struct rtl_works {
+       struct ieee80211_hw *hw;
+
+       /*timer */
+       struct timer_list watchdog_timer;
+       struct timer_list dualmac_easyconcurrent_retrytimer;
+       struct timer_list fw_clockoff_timer;
+       struct timer_list fast_antenna_trainning_timer;
+       /*task */
+       struct tasklet_struct irq_tasklet;
+       struct tasklet_struct irq_prepare_bcn_tasklet;
+
+       /*work queue */
+       struct workqueue_struct *rtl_wq;
+       struct delayed_work watchdog_wq;
+       struct delayed_work ips_nic_off_wq;
+
+       /* For SW LPS */
+       struct delayed_work ps_work;
+       struct delayed_work ps_rfon_wq;
+       struct delayed_work fwevt_wq;
+};
+
+struct rtl_debug {
+       u32 dbgp_type[DBGP_TYPE_MAX];
+       u32 global_debuglevel;
+       u64 global_debugcomponents;
+
+       /* add for proc debug */
+       struct proc_dir_entry *proc_dir;
+       char proc_name[20];
+};
+
+#define MIMO_PS_STATIC                 0
+#define MIMO_PS_DYNAMIC                        1
+#define MIMO_PS_NOLIMIT                        3
+
+struct rtl_dualmac_easy_concurrent_ctl {
+       enum band_type currentbandtype_backfordmdp;
+       bool bclose_bbandrf_for_dmsp;
+       bool bchange_to_dmdp;
+       bool bchange_to_dmsp;
+       bool bswitch_in_process;
+};
+
+struct rtl_dmsp_ctl {
+       bool bactivescan_for_slaveofdmsp;
+       bool bscan_for_anothermac_fordmsp;
+       bool bscan_for_itself_fordmsp;
+       bool bwritedig_for_anothermacofdmsp;
+       u32 curdigvalue_for_anothermacofdmsp;
+       bool bchangecckpdstate_for_anothermacofdmsp;
+       u8 curcckpdstate_for_anothermacofdmsp;
+       bool bchangetxhighpowerlvl_for_anothermacofdmsp;
+       u8 curtxhighlvl_for_anothermacofdmsp;
+       long rssivalmin_for_anothermacofdmsp;
+};
+
+struct rtl_global_var {
+       /* from this list we can get
+        * other adapter's rtl_priv */
+       struct list_head glb_priv_list;
+       spinlock_t glb_list_lock;
+};
+
+struct rtl_btc_info {
+       u8 bt_type;
+       u8 btcoexist;
+       u8 ant_num;
+};
+
+struct rtl_btc_ops {
+       void (*btc_init_variables) (struct rtl_priv *rtlpriv);
+       void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv);
+       void (*btc_init_hw_config) (struct rtl_priv *rtlpriv);
+       void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type);
+       void (*btc_scan_notify) (struct rtl_priv *rtlpriv, u8 scantype);
+       void (*btc_connect_notify) (struct rtl_priv *rtlpriv, u8 action);
+       void (*btc_mediastatus_notify) (struct rtl_priv *rtlpriv,
+                                       enum rt_media_status mstatus);
+       void (*btc_periodical) (struct rtl_priv *rtlpriv);
+       void (*btc_halt_notify) (void);
+       void (*btc_btinfo_notify) (struct rtl_priv *rtlpriv,
+                                  u8 * tmp_buf, u8 length);
+       bool (*btc_is_limited_dig) (struct rtl_priv *rtlpriv);
+       bool (*btc_is_disable_edca_turbo) (struct rtl_priv *rtlpriv);
+       bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv);
+};
+
+struct rtl_bt_coexist {
+       struct rtl_btc_ops *btc_ops;
+       struct rtl_btc_info btc_info;
+};
+
+
+struct rtl_priv {
+       struct list_head list;
+#ifdef VIF_TODO
+       struct vif_priv vif_priv;
+#endif
+       struct rtl_priv *buddy_priv;
+       struct rtl_global_var *glb_var;
+       struct rtl_dualmac_easy_concurrent_ctl easy_concurrent_ctl;
+       struct rtl_dmsp_ctl dmsp_ctl;
+       struct rtl_locks locks;
+       struct rtl_works works;
+       struct rtl_mac mac80211;
+       struct rtl_hal rtlhal;
+       struct rtl_regulatory regd;
+       struct rtl_rfkill rfkill;
+       struct rtl_io io;
+       struct rtl_phy phy;
+       struct rtl_dm dm;
+       struct rtl_security sec;
+       struct rtl_efuse efuse;
+
+       struct rtl_ps_ctl psc;
+       struct rate_adaptive ra;
+       struct dynamic_primary_cca primarycca;
+       struct wireless_stats stats;
+       struct rt_link_detect link_info;
+       struct false_alarm_statistics falsealm_cnt;
+
+       struct rtl_rate_priv *rate_priv;
+
+       struct rtl_debug dbg;
+
+       /* sta entry list for ap adhoc or mesh */
+       struct list_head entry_list;
+
+       /*
+        *hal_cfg : for diff cards
+        *intf_ops : for diff interrface usb/pcie
+        */
+       struct rtl_hal_cfg *cfg;
+       struct rtl_intf_ops *intf_ops;
+
+       /*this var will be set by set_bit,
+          and was used to indicate status of
+          interface or hardware */
+       unsigned long status;
+
+       /* intel Proximity, should be alloc mem
+        * in intel Proximity module and can only
+        * be used in intel Proximity mode */
+       struct proxim proximity;
+
+       /*for bt coexist use*/
+       struct rtl_bt_coexist btcoexist;
+
+       /* seperate 92ee from other ICs,
+         * 92ee use new trx flow. */
+       bool use_new_trx_flow;
+       /*This must be the last item so
+          that it points to the data allocated
+          beyond  this structure like:
+          rtl_pci_priv or rtl_usb_priv */
+       u8 priv[0];
+};
+
+#define rtl_priv(hw)           (((struct rtl_priv *)(hw)->priv))
+#define rtl_mac(rtlpriv)       (&((rtlpriv)->mac80211))
+#define rtl_hal(rtlpriv)       (&((rtlpriv)->rtlhal))
+#define rtl_efuse(rtlpriv)     (&((rtlpriv)->efuse))
+#define rtl_psc(rtlpriv)       (&((rtlpriv)->psc))
+#define rtl_sec(rtlpriv)       (&((rtlpriv)->sec))
+#define rtl_dm(rtlpriv)        (&((rtlpriv)->dm))
+/***************************************
+    Bluetooth Co-existance Related
+****************************************/
+
+enum bt_ant_num {
+        ANT_X2 = 0,
+        ANT_X1 = 1,
+};
+
+enum bt_co_type {
+        BT_2WIRE = 0,
+        BT_ISSC_3WIRE = 1,
+        BT_ACCEL = 2,
+        BT_CSR_BC4 = 3,
+        BT_CSR_BC8 = 4,
+        BT_RTL8756 = 5,
+        BT_RTL8723A = 6,
+        BT_RTL8821A = 7,
+        BT_RTL8723B = 8,
+        BT_RTL8192E = 9,
+        BT_RTL8812A = 11,
+};
+
+enum bt_total_ant_num{
+       ANT_TOTAL_X2 = 0,
+       ANT_TOTAL_X1 = 1
+};
+
+enum bt_cur_state {
+        BT_OFF = 0,
+        BT_ON = 1,
+};
+
+enum bt_service_type {
+        BT_SCO = 0,
+        BT_A2DP = 1,
+        BT_HID = 2,
+        BT_HID_IDLE = 3,
+        BT_SCAN = 4,
+        BT_IDLE = 5,
+        BT_OTHER_ACTION = 6,
+        BT_BUSY = 7,
+        BT_OTHERBUSY = 8,
+        BT_PAN = 9,
+};
+
+enum bt_radio_shared {
+        BT_RADIO_SHARED = 0,
+        BT_RADIO_INDIVIDUAL = 1,
+};
+
+struct bt_coexist_info {
+
+       /* EEPROM BT info. */
+       u8 eeprom_bt_coexist;
+       u8 eeprom_bt_type;
+       u8 eeprom_bt_ant_num;
+       u8 eeprom_bt_ant_isolation;
+       u8 eeprom_bt_radio_shared;
+
+       u8 bt_coexistence;
+       u8 bt_ant_num;
+       u8 bt_coexist_type;
+       u8 bt_state;
+       u8 bt_cur_state;        /* 0:on, 1:off */
+       u8 bt_ant_isolation;    /* 0:good, 1:bad */
+       u8 bt_pape_ctrl;        /* 0:SW, 1:SW/HW dynamic */
+       u8 bt_service;
+       u8 bt_radio_shared_type;
+       u8 bt_rfreg_origin_1e;
+       u8 bt_rfreg_origin_1f;
+       u8 bt_rssi_state;
+       u32 ratio_tx;
+       u32 ratio_pri;
+       u32 bt_edca_ul;
+       u32 bt_edca_dl;
+
+       bool b_init_set;
+       bool b_bt_busy_traffic;
+       bool b_bt_traffic_mode_set;
+       bool b_bt_non_traffic_mode_set;
+
+       bool b_fw_coexist_all_off;
+       bool b_sw_coexist_all_off;
+       bool b_hw_coexist_all_off;
+       u32 current_state;
+       u32 previous_state;
+       u32 current_state_h;
+       u32 previous_state_h;
+
+       u8 bt_pre_rssi_state;
+       u8 bt_pre_rssi_state1;
+
+       u8 b_reg_bt_iso;
+       u8 b_reg_bt_sco;
+       bool b_balance_on;
+       u8 bt_active_zero_cnt;
+       bool b_cur_bt_disabled;
+       bool b_pre_bt_disabled;
+
+       u8 bt_profile_case;
+       u8 bt_profile_action;
+       bool b_bt_busy;
+       bool b_hold_for_bt_operation;
+       u8 lps_counter;
+};
+
+
+/****************************************
+       mem access macro define start
+       Call endian free function when
+       1. Read/write packet content.
+       2. Before write integer to IO.
+       3. After read integer from IO.
+****************************************/
+/* Convert little data endian to host */
+#define EF1BYTE(_val)          \
+       ((u8)(_val))
+#define EF2BYTE(_val)          \
+       (le16_to_cpu(_val))
+#define EF4BYTE(_val)          \
+       (le32_to_cpu(_val))
+
+/* Read data from memory */
+#define READEF1BYTE(_ptr)      \
+       EF1BYTE(*((u8 *)(_ptr)))
+#define READEF2BYTE(_ptr)      \
+       EF2BYTE(*((u16 *)(_ptr)))
+#define READEF4BYTE(_ptr)      \
+       EF4BYTE(*((u32 *)(_ptr)))
+
+/* Write data to memory */
+#define WRITEEF1BYTE(_ptr, _val)       \
+       (*((u8 *)(_ptr)))=EF1BYTE(_val)
+#define WRITEEF2BYTE(_ptr, _val)       \
+       (*((u16 *)(_ptr)))=EF2BYTE(_val)
+#define WRITEEF4BYTE(_ptr, _val)       \
+       (*((u32 *)(_ptr)))=EF4BYTE(_val)
+
+/*Example:
+BIT_LEN_MASK_32(0) => 0x00000000
+BIT_LEN_MASK_32(1) => 0x00000001
+BIT_LEN_MASK_32(2) => 0x00000003
+BIT_LEN_MASK_32(32) => 0xFFFFFFFF*/
+#define BIT_LEN_MASK_32(__bitlen)       \
+       (0xFFFFFFFF >> (32 - (__bitlen)))
+#define BIT_LEN_MASK_16(__bitlen)       \
+       (0xFFFF >> (16 - (__bitlen)))
+#define BIT_LEN_MASK_8(__bitlen) \
+       (0xFF >> (8 - (__bitlen)))
+
+/*Example:
+BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003
+BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000*/
+#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \
+       (BIT_LEN_MASK_32(__bitlen) << (__bitoffset))
+#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \
+       (BIT_LEN_MASK_16(__bitlen) << (__bitoffset))
+#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \
+       (BIT_LEN_MASK_8(__bitlen) << (__bitoffset))
+
+/*Description:
+Return 4-byte value in host byte ordering from
+4-byte pointer in little-endian system.*/
+#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \
+       (EF4BYTE(*((u32 *)(__pstart))))
+#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \
+       (EF2BYTE(*((u16 *)(__pstart))))
+#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \
+       (EF1BYTE(*((u8 *)(__pstart))))
+
+/*Description:
+Translate subfield (continuous bits in little-endian) of 4-byte
+value to host byte ordering.*/
+#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
+       ( \
+               ( LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset) )  & \
+               BIT_LEN_MASK_32(__bitlen) \
+       )
+#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
+       ( \
+               ( LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset) ) & \
+               BIT_LEN_MASK_16(__bitlen) \
+       )
+#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
+       ( \
+               ( LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset) ) & \
+               BIT_LEN_MASK_8(__bitlen) \
+       )
+
+/*Description:
+Mask subfield (continuous bits in little-endian) of 4-byte value
+and return the result in 4-byte value in host byte ordering.*/
+#define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
+       ( \
+               LE_P4BYTE_TO_HOST_4BYTE(__pstart)  & \
+               ( ~BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) ) \
+       )
+#define LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
+       ( \
+               LE_P2BYTE_TO_HOST_2BYTE(__pstart) & \
+               ( ~BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) ) \
+       )
+#define LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
+       ( \
+               LE_P1BYTE_TO_HOST_1BYTE(__pstart) & \
+               ( ~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) ) \
+       )
+
+/*Description:
+Set subfield of little-endian 4-byte value to specified value. */
+#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \
+       *((u32 *)(__pstart)) = EF4BYTE \
+       ( \
+               LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \
+               ( (((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset) )\
+       );
+#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \
+       *((u16 *)(__pstart)) = EF2BYTE \
+       ( \
+               LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \
+               ( (((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset) )\
+       );
+#define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \
+       *((u8 *)(__pstart)) = EF1BYTE \
+       ( \
+               LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) | \
+               ( (((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset) ) \
+       );
+
+#define        N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \
+       (__value) : (((__value + __aligment - 1) / __aligment) * __aligment))
+
+/****************************************
+       mem access macro define end
+****************************************/
+
+#define byte(x,n) ((x >> (8 * n)) & 0xff)
+
+#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC)
+#define RTL_WATCH_DOG_TIME     2000
+#define MSECS(t)               msecs_to_jiffies(t)
+#define WLAN_FC_GET_VERS(fc)   ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc)   ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc)  ((fc) & IEEE80211_FCTL_STYPE)
+#define WLAN_FC_MORE_DATA(fc)  ((fc) & IEEE80211_FCTL_MOREDATA)
+#define SEQ_TO_SN(seq)                 (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+#define SN_TO_SEQ(ssn)                 (((ssn) << 4) & IEEE80211_SCTL_SEQ)
+#define MAX_SN                         ((IEEE80211_SCTL_SEQ) >> 4)
+
+#define        RT_RF_OFF_LEVL_ASPM             BIT(0)  /*PCI ASPM */
+#define        RT_RF_OFF_LEVL_CLK_REQ          BIT(1)  /*PCI clock request */
+#define        RT_RF_OFF_LEVL_PCI_D3           BIT(2)  /*PCI D3 mode */
+/*NIC halt, re-initialize hw parameters*/
+#define        RT_RF_OFF_LEVL_HALT_NIC         BIT(3)
+#define        RT_RF_OFF_LEVL_FREE_FW          BIT(4)  /*FW free, re-download the FW */
+#define        RT_RF_OFF_LEVL_FW_32K           BIT(5)  /*FW in 32k */
+/*Always enable ASPM and Clock Req in initialization.*/
+#define        RT_RF_PS_LEVEL_ALWAYS_ASPM      BIT(6)
+/* no matter RFOFF or SLEEP we set PS_ASPM_LEVL*/
+#define        RT_PS_LEVEL_ASPM                BIT(7)
+/*When LPS is on, disable 2R if no packet is received or transmittd.*/
+#define        RT_RF_LPS_DISALBE_2R            BIT(30)
+#define        RT_RF_LPS_LEVEL_ASPM            BIT(31) /*LPS with ASPM */
+#define        RT_IN_PS_LEVEL(ppsc, _ps_flg)           \
+       ((ppsc->cur_ps_level & _ps_flg) ? true : false)
+#define        RT_CLEAR_PS_LEVEL(ppsc, _ps_flg)        \
+       (ppsc->cur_ps_level &= (~(_ps_flg)))
+#define        RT_SET_PS_LEVEL(ppsc, _ps_flg)          \
+       (ppsc->cur_ps_level |= _ps_flg)
+
+#define container_of_dwork_rtl(x,y,z) \
+       container_of(container_of(x, struct delayed_work, work), y, z)
+
+#define FILL_OCTET_STRING(_os,_octet,_len)     \
+               (_os).octet=(u8*)(_octet);              \
+               (_os).length=(_len);
+
+#define CP_MACADDR(des,src)    \
+       ((des)[0]=(src)[0],(des)[1]=(src)[1],\
+       (des)[2]=(src)[2],(des)[3]=(src)[3],\
+       (des)[4]=(src)[4],(des)[5]=(src)[5])
+
+static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)
+{
+       return rtlpriv->io.read8_sync(rtlpriv, addr);
+}
+
+static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr)
+{
+       return rtlpriv->io.read16_sync(rtlpriv, addr);
+}
+
+static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr)
+{
+       return rtlpriv->io.read32_sync(rtlpriv, addr);
+}
+
+static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8)
+{
+       rtlpriv->io.write8_async(rtlpriv, addr, val8);
+
+       if (rtlpriv->cfg->write_readback)
+               rtlpriv->io.read8_sync(rtlpriv, addr);
+}
+
+static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16)
+{
+       rtlpriv->io.write16_async(rtlpriv, addr, val16);
+
+       if (rtlpriv->cfg->write_readback)
+               rtlpriv->io.read16_sync(rtlpriv, addr);
+}
+
+static inline void rtl_write_dword(struct rtl_priv *rtlpriv,
+                                  u32 addr, u32 val32)
+{
+       rtlpriv->io.write32_async(rtlpriv, addr, val32);
+
+       if (rtlpriv->cfg->write_readback)
+               rtlpriv->io.read32_sync(rtlpriv, addr);
+}
+
+static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw,
+                               u32 regaddr, u32 bitmask)
+{
+       return ((struct rtl_priv *)(hw)->priv)->cfg->ops->get_bbreg(hw,
+                                                                   regaddr,
+                                                                   bitmask);
+}
+
+static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr,
+                                u32 bitmask, u32 data)
+{
+       ((struct rtl_priv *)(hw)->priv)->cfg->ops->set_bbreg(hw,
+                                                            regaddr, bitmask,
+                                                            data);
+
+}
+
+static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw,
+                               enum radio_path rfpath, u32 regaddr,
+                               u32 bitmask)
+{
+       return ((struct rtl_priv *)(hw)->priv)->cfg->ops->get_rfreg(hw,
+                                                                   rfpath,
+                                                                   regaddr,
+                                                                   bitmask);
+}
+
+static inline void rtl_set_rfreg(struct ieee80211_hw *hw,
+                                enum radio_path rfpath, u32 regaddr,
+                                u32 bitmask, u32 data)
+{
+       ((struct rtl_priv *)(hw)->priv)->cfg->ops->set_rfreg(hw,
+                                                            rfpath, regaddr,
+                                                            bitmask, data);
+}
+
+static inline bool is_hal_stop(struct rtl_hal *rtlhal)
+{
+       return (_HAL_STATE_STOP == rtlhal->state);
+}
+
+static inline void set_hal_start(struct rtl_hal *rtlhal)
+{
+       rtlhal->state = _HAL_STATE_START;
+}
+
+static inline void set_hal_stop(struct rtl_hal *rtlhal)
+{
+       rtlhal->state = _HAL_STATE_STOP;
+}
+
+static inline u8 get_rf_type(struct rtl_phy *rtlphy)
+{
+       return rtlphy->rf_type;
+}
+
+static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb)
+{
+       return (struct ieee80211_hdr *)(skb->data);
+}
+
+static inline u16 rtl_get_fc(struct sk_buff *skb)
+{
+       return le16_to_cpu(rtl_get_hdr(skb)->frame_control);
+}
+
+static inline u16 rtl_get_tid_h(struct ieee80211_hdr *hdr)
+{
+       return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
+static inline u16 rtl_get_tid(struct sk_buff *skb)
+{
+       return rtl_get_tid_h(rtl_get_hdr(skb));
+}
+
+static inline struct ieee80211_sta *rtl_find_sta(struct ieee80211_hw *hw,
+                                                u8 *mac_addr)
+{
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       return ieee80211_find_sta(mac->vif, mac_addr);
+}
+
+struct ieee80211_hw *rtl_pci_get_hw_pointer(void);
+#endif