]> Pileus Git - ~andy/linux/commitdiff
Staging: rtl8812ae: Add Realtek 8821 PCI WIFI driver
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Jan 2014 19:20:45 +0000 (11:20 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Jan 2014 17:37:23 +0000 (09:37 -0800)
This comes directly from the Realtek tarball, filename:
wifi_driver_8821ae_0018.1129.2013.tar.gz

I mushed the three modules (btcoexist, rtlwifi and rtl8821ae) together
into one, in order to make it all build as one stand-alone module.
After the btcoexist driver gets merged upstream, I'll pull it out of
here, and will continue to work on removing this version of rtlwifi in
order to use the in-kernel one.

Cc: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
74 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/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 4bb6b11166b33544958634157dcabbe2f09ad0b2..810bcb31740ac5b8b7f89f9255d5ae513ea4e125 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 9f07e5e160942bb8744b895fe08791ef3fcbe684..d925cde979cf330388a4ab931b7618953376071f 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..2aa5dac
--- /dev/null
@@ -0,0 +1,11 @@
+config R8821AE
+       tristate "RealTek RTL8821AE Wireless LAN NIC driver"
+       depends on PCI && WLAN
+       depends on m
+       select WIRELESS_EXT
+       select WEXT_PRIV
+       select EEPROM_93CX6
+       select CRYPTO
+       default N
+       ---help---
+         If built as a module, it will be called r8821ae.ko.
diff --git a/drivers/staging/rtl8821ae/Makefile b/drivers/staging/rtl8821ae/Makefile
new file mode 100644 (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/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..70afdce
--- /dev/null
@@ -0,0 +1,307 @@
+/******************************************************************************
+ *
+ * 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 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 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..881ea11
--- /dev/null
@@ -0,0 +1,3166 @@
+/******************************************************************************
+ *
+ * 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_initialize_txpower_tracking(struct ieee80211_hw *hw)
+{
+       rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw);
+}
+
+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_mac *mac = rtl_mac(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_dynamic_txpower(struct ieee80211_hw *hw)
+{
+       /* 8723BE does not support ODM_BB_DYNAMIC_TXPWR*/
+       return;
+}
+
+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;
+       }
+}
+
+
+static void rtl8821ae_set_iqk_matrix(struct ieee80211_hw *hw,
+       u8 ofdm_index,
+       u8 rfpath,
+       long iqk_result_x,
+       long iqk_result_y)
+{
+       long ele_a = 0, ele_d, ele_c = 0, value32;
+
+       if (ofdm_index >= OFDM_TABLE_SIZE)
+               ofdm_index = OFDM_TABLE_SIZE - 1;
+       else if (ofdm_index < 0)
+               ofdm_index = 0;
+
+       ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22;
+
+       if (iqk_result_x != 0){
+               if ((iqk_result_x & 0x00000200) != 0)
+                       iqk_result_x = iqk_result_x | 0xFFFFFC00;
+               ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF;
+
+               if ((iqk_result_y & 0x00000200) != 0)
+                       iqk_result_y = iqk_result_y | 0xFFFFFC00;
+               ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF;
+
+               switch (rfpath){
+                       case RF90_PATH_A:
+                               value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
+                               rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, value32);
+                               value32 = (ele_c & 0x000003C0) >> 6;
+                               rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
+                               value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
+                               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), value32);
+                               break;
+                       default:
+                               break;
+               }
+       } else {
+               switch (rfpath){
+                       case RF90_PATH_A:
+                               rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, ofdmswing_table[ofdm_index]);
+                               rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
+                               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00);
+                               break;
+                       default:
+                               break;
+               }
+       }
+}
+
+
+static void rtl8821ae_dm_tx_power_track_set_power(struct ieee80211_hw *hw,
+       enum pwr_track_control_method method,
+       u8 rfpath,
+       u8 channel_mapped_index)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
+
+       if (method == TXAGC) {
+                       rtl8821ae_phy_set_txpower_level(hw,rtlphy->current_channel);
+       } else if (method == BBSWING) {
+               if (rtldm->bb_swing_idx_cck >= CCK_TABLE_SIZE)
+                       rtldm->bb_swing_idx_cck = CCK_TABLE_SIZE-1;
+               else if (rtldm->bb_swing_idx_cck < 0)
+                       rtldm->bb_swing_idx_cck = 0;
+
+               if (!rtldm->b_cck_inch14) {
+                       rtl_write_byte(rtlpriv, 0xa22, cckswing_table_ch1ch13[rtldm->bb_swing_idx_cck][0]);
+                       rtl_write_byte(rtlpriv, 0xa23, cckswing_table_ch1ch13[rtldm->bb_swing_idx_cck][1]);
+                       rtl_write_byte(rtlpriv, 0xa24, cckswing_table_ch1ch13[rtldm->bb_swing_idx_cck][2]);
+                       rtl_write_byte(rtlpriv, 0xa25, cckswing_table_ch1ch13[rtldm->bb_swing_idx_cck][3]);
+                       rtl_write_byte(rtlpriv, 0xa26, cckswing_table_ch1ch13[rtldm->bb_swing_idx_cck][4]);
+                       rtl_write_byte(rtlpriv, 0xa27, cckswing_table_ch1ch13[rtldm->bb_swing_idx_cck][5]);
+                       rtl_write_byte(rtlpriv, 0xa28, cckswing_table_ch1ch13[rtldm->bb_swing_idx_cck][6]);
+                       rtl_write_byte(rtlpriv, 0xa29, cckswing_table_ch1ch13[rtldm->bb_swing_idx_cck][7]);
+               } else{
+                       rtl_write_byte(rtlpriv, 0xa22, cckswing_table_ch14[rtldm->bb_swing_idx_cck][0]);
+                       rtl_write_byte(rtlpriv, 0xa23, cckswing_table_ch14[rtldm->bb_swing_idx_cck][1]);
+                       rtl_write_byte(rtlpriv, 0xa24, cckswing_table_ch14[rtldm->bb_swing_idx_cck][2]);
+                       rtl_write_byte(rtlpriv, 0xa25, cckswing_table_ch14[rtldm->bb_swing_idx_cck][3]);
+                       rtl_write_byte(rtlpriv, 0xa26, cckswing_table_ch14[rtldm->bb_swing_idx_cck][4]);
+                       rtl_write_byte(rtlpriv, 0xa27, cckswing_table_ch14[rtldm->bb_swing_idx_cck][5]);
+                       rtl_write_byte(rtlpriv, 0xa28, cckswing_table_ch14[rtldm->bb_swing_idx_cck][6]);
+                       rtl_write_byte(rtlpriv, 0xa29, cckswing_table_ch14[rtldm->bb_swing_idx_cck][7]);
+               }
+
+               if (rfpath == RF90_PATH_A){
+                       rtl8821ae_set_iqk_matrix(hw, rtldm->bb_swing_idx_ofdm[rfpath], rfpath,
+                               rtlphy->iqk_matrix_regsetting[channel_mapped_index].value[0][0],
+                               rtlphy->iqk_matrix_regsetting[channel_mapped_index].value[0][1]);
+               } else if (rfpath == RF90_PATH_B) {
+                       rtl8821ae_set_iqk_matrix(hw, rtldm->bb_swing_idx_ofdm[rfpath], rfpath,
+                               rtlphy->iqk_matrix_regsetting[channel_mapped_index].value[0][4],
+                               rtlphy->iqk_matrix_regsetting[channel_mapped_index].value[0][5]);
+               }
+       } else {
+               return;
+       }
+}
+
+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);
+       bool b_start_cont_tx = false, b_single_tone = false, b_carrier_suppression = false;
+
+
+       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;
+       char final_cck_swing_index = 0;
+       u8 i = 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);
+       bool b_start_cont_tx = false, b_single_tone = false, b_carrier_suppression = false;
+
+
+       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;
+       char final_cck_swing_index = 0;
+       u8 i = 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..89ce456
--- /dev/null
@@ -0,0 +1,1354 @@
+/******************************************************************************
+ *
+ * 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_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       u8 rate = cmd_buf[0] & 0x3F;
+       u8 mac_id = cmd_buf[1];
+       bool b_ldpc = cmd_buf[2] & BIT(0);
+       bool b_tx_bf = (cmd_buf[2] & BIT(1)) >> 1;
+
+       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..2532b89
--- /dev/null
@@ -0,0 +1,5749 @@
+/******************************************************************************
+ *
+ * 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;
+}
+
+static u8 _rtl8821ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
+{
+       u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
+       u8 result = 0x00;
+
+       rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
+       rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
+       rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
+       rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
+
+       rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
+       rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
+       rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
+
+       mdelay(IQK_DELAY_TIME);
+
+       reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
+       reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
+       reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
+       reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
+
+       if (!(reg_eac & BIT(28)) &&
+           (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
+           (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
+               result |= 0x01;
+       else
+               return result;
+/*
+       if (!(reg_eac & BIT(27)) &&
+           (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
+           (((reg_eac & 0x03FF0000) >> 16) != 0x36))
+               result |= 0x02;*/
+       return result;
+}
+#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
+static void _rtl8821ae_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
+                                              bool b_iqk_ok, long result[][8],
+                                              u8 final_candidate, bool btxonly)
+{
+       u32 oldval_0, x, tx0_a, reg;
+       long y, tx0_c;
+
+       if (final_candidate == 0xFF) {
+               return;
+       } else if (b_iqk_ok) {
+               oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
+                                         MASKDWORD) >> 22) & 0x3FF;
+               x = result[final_candidate][0];
+               if ((x & 0x00000200) != 0)
+                       x = x | 0xFFFFFC00;
+               tx0_a = (x * oldval_0) >> 8;
+               rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
+               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
+                             ((x * oldval_0 >> 7) & 0x1));
+               y = result[final_candidate][1];
+               if ((y & 0x00000200) != 0)
+                       y = y | 0xFFFFFC00;
+               tx0_c = (y * oldval_0) >> 8;
+               rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
+                             ((tx0_c & 0x3C0) >> 6));
+               rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
+                             (tx0_c & 0x3F));
+               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
+                             ((y * oldval_0 >> 7) & 0x1));
+               if (btxonly)
+                       return;
+               reg = result[final_candidate][2];
+               rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
+               reg = result[final_candidate][3] & 0x3F;
+               rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
+               reg = (result[final_candidate][3] >> 6) & 0xF;
+               rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
+       }
+}
+
+
+static void _rtl8821ae_phy_save_adda_registers(struct ieee80211_hw *hw,
+                                           u32 *addareg, u32 *addabackup,
+                                           u32 registernum)
+{
+       u32 i;
+
+       for (i = 0; i < registernum; i++)
+               addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
+}
+
+static void _rtl8821ae_phy_save_mac_registers(struct ieee80211_hw *hw,
+                                          u32 *macreg, u32 *macbackup)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
+               macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
+       macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
+}
+
+static void _rtl8821ae_phy_reload_adda_registers(struct ieee80211_hw *hw,
+                                             u32 *addareg, u32 *addabackup,
+                                             u32 regiesternum)
+{
+       u32 i;
+
+       for (i = 0; i < regiesternum; i++)
+               rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
+}
+
+static void _rtl8821ae_phy_reload_mac_registers(struct ieee80211_hw *hw,
+                                            u32 *macreg, u32 *macbackup)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
+               rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
+       rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
+}
+
+static void _rtl8821ae_phy_path_adda_on(struct ieee80211_hw *hw,
+                                    u32 *addareg, bool is_patha_on, bool is2t)
+{
+       u32 pathOn;
+       u32 i;
+
+       pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
+       if (false == is2t) {
+               pathOn = 0x0bdb25a0;
+               rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
+       } else {
+               rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
+       }
+
+       for (i = 1; i < IQK_ADDA_REG_NUM; i++)
+               rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
+}
+
+static void _rtl8821ae_phy_mac_setting_calibration(struct ieee80211_hw *hw,
+                                               u32 *macreg, u32 *macbackup)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i = 0;
+
+       rtl_write_byte(rtlpriv, macreg[i], 0x3F);
+
+       for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
+               rtl_write_byte(rtlpriv, macreg[i],
+                              (u8) (macbackup[i] & (~BIT(3))));
+       rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
+}
+
+static void _rtl8821ae_phy_path_a_standby(struct ieee80211_hw *hw)
+{
+       rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
+       rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
+       rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
+}
+
+static void _rtl8821ae_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
+{
+       u32 mode;
+
+       mode = pi_mode ? 0x01000100 : 0x01000000;
+       rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
+       rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
+}
+
+static bool _rtl8821ae_phy_simularity_compare(struct ieee80211_hw *hw,
+                                          long result[][8], u8 c1, u8 c2)
+{
+       u32 i, j, diff, simularity_bitmap, bound;
+       //struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       u8 final_candidate[2] = { 0xFF, 0xFF };
+       bool bresult = true, is2t = true;//= IS_92C_SERIAL(rtlhal->version);
+
+       if (is2t)
+               bound = 8;
+       else
+               bound = 4;
+
+       simularity_bitmap = 0;
+
+       for (i = 0; i < bound; i++) {
+               diff = (result[c1][i] > result[c2][i]) ?
+                   (result[c1][i] - result[c2][i]) :
+                   (result[c2][i] - result[c1][i]);
+
+               if (diff > MAX_TOLERANCE) {
+                       if ((i == 2 || i == 6) && !simularity_bitmap) {
+                               if (result[c1][i] + result[c1][i + 1] == 0)
+                                       final_candidate[(i / 4)] = c2;
+                               else if (result[c2][i] + result[c2][i + 1] == 0)
+                                       final_candidate[(i / 4)] = c1;
+                               else
+                                       simularity_bitmap = simularity_bitmap |
+                                           (1 << i);
+                       } else
+                               simularity_bitmap =
+                                   simularity_bitmap | (1 << i);
+               }
+       }
+
+       if (simularity_bitmap == 0) {
+               for (i = 0; i < (bound / 4); i++) {
+                       if (final_candidate[i] != 0xFF) {
+                               for (j = i * 4; j < (i + 1) * 4 - 2; j++)
+                                       result[3][j] =
+                                           result[final_candidate[i]][j];
+                               bresult = false;
+                       }
+               }
+               return bresult;
+       } else if (!(simularity_bitmap & 0x0F)) {
+               for (i = 0; i < 4; i++)
+                       result[3][i] = result[c1][i];
+               return false;
+       } else if (!(simularity_bitmap & 0xF0) && is2t) {
+               for (i = 4; i < 8; i++)
+                       result[3][i] = result[c1][i];
+               return false;
+       } else {
+               return false;
+       }
+
+}
+
+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, cal = 0;
+       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, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3], ii, dx = 0, dy = 0, dt = 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..6a172c9
--- /dev/null
@@ -0,0 +1,1051 @@
+/******************************************************************************
+ *
+ * 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 rtl_dm *rtldm = rtl_dm(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