From 5c0f83544c883c6c38027588df8b754b6d5caab9 Mon Sep 17 00:00:00 2001
From: The-going <48602507+The-going@users.noreply.github.com>
Date: Mon, 7 Feb 2022 15:26:37 +0300
Subject: [PATCH 8/9] drv:net:rtl8723cs:hal base, rtl8703b, led, efuse

---
 .../realtek/rtl8723cs/hal/HalPwrSeqCmd.c      |  183 +
 .../realtek/rtl8723cs/hal/efuse/efuse_mask.h  |   80 +
 .../efuse/rtl8703b/HalEfuseMask8703B_PCIE.c   |  101 +
 .../efuse/rtl8703b/HalEfuseMask8703B_PCIE.h   |   40 +
 .../efuse/rtl8703b/HalEfuseMask8703B_SDIO.c   |  102 +
 .../efuse/rtl8703b/HalEfuseMask8703B_SDIO.h   |   41 +
 .../efuse/rtl8703b/HalEfuseMask8703B_USB.c    |   99 +
 .../efuse/rtl8703b/HalEfuseMask8703B_USB.h    |   42 +
 .../realtek/rtl8723cs/hal/hal_btcoex.c        | 4044 ++++++++
 .../wireless/realtek/rtl8723cs/hal/hal_com.c  | 8102 +++++++++++++++++
 .../realtek/rtl8723cs/hal/hal_com_c2h.h       |   50 +
 .../realtek/rtl8723cs/hal/hal_com_phycfg.c    | 4440 +++++++++
 .../wireless/realtek/rtl8723cs/hal/hal_dm.c   |  195 +
 .../wireless/realtek/rtl8723cs/hal/hal_dm.h   |   26 +
 .../realtek/rtl8723cs/hal/hal_hci/hal_sdio.c  |  112 +
 .../wireless/realtek/rtl8723cs/hal/hal_intf.c | 1128 +++
 .../wireless/realtek/rtl8723cs/hal/hal_mp.c   | 1799 ++++
 .../wireless/realtek/rtl8723cs/hal/hal_phy.c  |  285 +
 .../realtek/rtl8723cs/hal/led/hal_sdio_led.c  | 2420 +++++
 .../rtl8723cs/hal/rtl8703b/Hal8703BPwrSeq.c   |   94 +
 .../rtl8723cs/hal/rtl8703b/rtl8703b_cmd.c     | 1373 +++
 .../rtl8723cs/hal/rtl8703b/rtl8703b_dm.c      |  565 ++
 .../hal/rtl8703b/rtl8703b_hal_init.c          | 7377 +++++++++++++++
 .../rtl8723cs/hal/rtl8703b/rtl8703b_phycfg.c  | 1559 ++++
 .../rtl8723cs/hal/rtl8703b/rtl8703b_rf6052.c  |  268 +
 .../rtl8723cs/hal/rtl8703b/rtl8703b_rxdesc.c  |   69 +
 .../rtl8723cs/hal/rtl8703b/rtl8703b_sreset.c  |  111 +
 .../hal/rtl8703b/sdio/rtl8703bs_led.c         |  127 +
 .../hal/rtl8703b/sdio/rtl8703bs_recv.c        |  711 ++
 .../hal/rtl8703b/sdio/rtl8703bs_xmit.c        |  769 ++
 .../hal/rtl8703b/sdio/sdio_halinit.c          | 2021 ++++
 .../rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c    | 1813 ++++
 32 files changed, 40146 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/HalPwrSeqCmd.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/efuse/efuse_mask.h
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_PCIE.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_PCIE.h
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_SDIO.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_SDIO.h
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_USB.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_USB.h
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_btcoex.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_com.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_com_c2h.h
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_com_phycfg.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_dm.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_dm.h
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_hci/hal_sdio.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_intf.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_mp.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/hal_phy.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/led/hal_sdio_led.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/Hal8703BPwrSeq.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_cmd.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_dm.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_hal_init.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_phycfg.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_rf6052.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_rxdesc.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_sreset.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_led.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_recv.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_xmit.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/sdio_halinit.c
 create mode 100644 drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c

diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/HalPwrSeqCmd.c b/drivers/net/wireless/realtek/rtl8723cs/hal/HalPwrSeqCmd.c
new file mode 100644
index 000000000..6d063aa98
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/HalPwrSeqCmd.c
@@ -0,0 +1,183 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+/*++
+Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+
+Module Name:
+	HalPwrSeqCmd.c
+
+Abstract:
+	Implement HW Power sequence configuration CMD handling routine for Realtek devices.
+
+Major Change History:
+	When       Who               What
+	---------- ---------------   -------------------------------
+	2011-10-26 Lucas            Modify to be compatible with SD4-CE driver.
+	2011-07-07 Roger            Create.
+
+--*/
+#include <HalPwrSeqCmd.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.
+//
+u8 HalPwrSeqCmdParsing(
+	PADAPTER		padapter,
+	u8				CutVersion,
+	u8				FabVersion,
+	u8				InterfaceType,
+	WLAN_PWR_CFG	PwrSeqCmd[])
+{
+	WLAN_PWR_CFG 	PwrCfgCmd = {0};
+	u8				bPollingBit = _FALSE;
+	u32				AryIdx = 0;
+	u8				value = 0;
+	u32				offset = 0;
+	u32				pollingCount = 0; // polling autoload done.
+	u32				maxPollingCnt = 5000;
+
+	do {
+		PwrCfgCmd = PwrSeqCmd[AryIdx];
+
+		RT_TRACE(_module_hal_init_c_ , _drv_info_,
+				 ("HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n",
+					GET_PWR_CFG_OFFSET(PwrCfgCmd),
+					GET_PWR_CFG_CUT_MASK(PwrCfgCmd),
+					GET_PWR_CFG_FAB_MASK(PwrCfgCmd),
+					GET_PWR_CFG_INTF_MASK(PwrCfgCmd),
+					GET_PWR_CFG_BASE(PwrCfgCmd),
+					GET_PWR_CFG_CMD(PwrCfgCmd),
+					GET_PWR_CFG_MASK(PwrCfgCmd),
+					GET_PWR_CFG_VALUE(PwrCfgCmd)));
+
+		//2 Only Handle the command whose FAB, CUT, and Interface are matched
+		if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
+			(GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
+			(GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType))
+		{
+			switch (GET_PWR_CFG_CMD(PwrCfgCmd))
+			{
+				case PWR_CMD_READ:
+					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_READ\n"));
+					break;
+
+				case PWR_CMD_WRITE:
+					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n"));
+					offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
+
+#ifdef CONFIG_SDIO_HCI
+					//
+					// <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface
+					// 2011.07.07.
+					//
+					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
+					{
+						// Read Back SDIO Local value
+						value = SdioLocalCmd52Read1Byte(padapter, offset);
+
+						value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
+						value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));
+
+						// Write Back SDIO Local value
+						SdioLocalCmd52Write1Byte(padapter, offset, value);
+					}
+					else
+#endif
+					{
+#ifdef CONFIG_GSPI_HCI
+						if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
+							offset = SPI_LOCAL_OFFSET | offset;
+#endif
+						// Read the value from system register
+						value = rtw_read8(padapter, offset);
+
+						value=value&(~(GET_PWR_CFG_MASK(PwrCfgCmd)));
+						value=value|(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd));
+
+						// Write the value back to sytem register
+						rtw_write8(padapter, offset, value);
+					}
+					break;
+
+				case PWR_CMD_POLLING:
+					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n"));
+
+					bPollingBit = _FALSE;
+					offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
+#ifdef CONFIG_GSPI_HCI
+					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
+						offset = SPI_LOCAL_OFFSET | offset;
+#endif
+					do {
+#ifdef CONFIG_SDIO_HCI
+						if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
+							value = SdioLocalCmd52Read1Byte(padapter, offset);
+						else
+#endif
+							value = rtw_read8(padapter, offset);
+
+						value=value&GET_PWR_CFG_MASK(PwrCfgCmd);
+						if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)))
+							bPollingBit = _TRUE;
+						else
+							rtw_udelay_os(10);
+
+						if (pollingCount++ > maxPollingCnt) {
+							DBG_871X_LEVEL(_drv_err_, "HalPwrSeqCmdParsing: Fail to polling Offset[%#x]=%02x\n", offset, value);
+							return _FALSE;
+						}
+					} while (!bPollingBit);
+
+					break;
+
+				case PWR_CMD_DELAY:
+					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n"));
+					if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
+						rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd));
+					else
+						rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000);
+					break;
+
+				case PWR_CMD_END:
+					// When this command is parsed, end the process
+					RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_END\n"));
+					return _TRUE;
+					break;
+
+				default:
+					RT_TRACE(_module_hal_init_c_ , _drv_err_, ("HalPwrSeqCmdParsing: Unknown CMD!!\n"));
+					break;
+			}
+		}
+
+		AryIdx++;//Add Array Index
+	}while(1);
+
+	return _TRUE;
+}
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/efuse_mask.h b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/efuse_mask.h
new file mode 100644
index 000000000..86041d443
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/efuse_mask.h
@@ -0,0 +1,80 @@
+
+#if DEV_BUS_TYPE == RT_USB_INTERFACE
+
+	#if defined(CONFIG_RTL8188E)
+	#include "rtl8188e/HalEfuseMask8188E_USB.h"
+	#endif
+
+	#if defined(CONFIG_RTL8812A)
+	#include "rtl8812a/HalEfuseMask8812A_USB.h"
+	#endif
+
+	#if defined(CONFIG_RTL8821A)
+	#include "rtl8812a/HalEfuseMask8821A_USB.h"
+	#endif
+
+	#if defined(CONFIG_RTL8192E)
+	#include "rtl8192e/HalEfuseMask8192E_USB.h"
+	#endif
+
+	#if defined(CONFIG_RTL8723B)
+	#include "rtl8723b/HalEfuseMask8723B_USB.h"
+	#endif
+
+	#if defined(CONFIG_RTL8814A)
+	#include "rtl8814a/HalEfuseMask8814A_USB.h"
+	#endif
+
+	#if defined(CONFIG_RTL8703B)
+	#include "rtl8703b/HalEfuseMask8703B_USB.h"
+	#endif
+
+	#if defined(CONFIG_RTL8188F)
+	#include "rtl8188f/HalEfuseMask8188F_USB.h"
+	#endif
+
+#elif DEV_BUS_TYPE == RT_PCI_INTERFACE
+
+	#if defined(CONFIG_RTL8188E)
+	#include "rtl8188e/HalEfuseMask8188E_PCIE.h"
+	#endif
+
+	#if defined(CONFIG_RTL8812A)
+	#include "rtl8812a/HalEfuseMask8812A_PCIE.h"
+	#endif
+
+	#if defined(CONFIG_RTL8821A)
+	#include "rtl8812a/HalEfuseMask8821A_PCIE.h"
+	#endif
+
+	#if defined(CONFIG_RTL8192E)
+	#include "rtl8192e/HalEfuseMask8192E_PCIE.h"
+	#endif
+
+	#if defined(CONFIG_RTL8723B)
+	#include "rtl8723b/HalEfuseMask8723B_PCIE.h"
+	#endif
+
+	#if defined(CONFIG_RTL8814A)
+	#include "rtl8814a/HalEfuseMask8814A_PCIE.h"
+	#endif
+
+	#if defined(CONFIG_RTL8703B)
+	#include "rtl8703b/HalEfuseMask8703B_PCIE.h"
+	#endif
+
+#elif DEV_BUS_TYPE == RT_SDIO_INTERFACE
+
+	#if defined(CONFIG_RTL8188E)
+	#include "rtl8188e/HalEfuseMask8188E_SDIO.h"
+	#endif
+
+	#if defined(CONFIG_RTL8703B)
+	#include "rtl8703b/HalEfuseMask8703B_SDIO.h"
+	#endif
+
+	#if defined(CONFIG_RTL8188F)
+	#include "rtl8188f/HalEfuseMask8188F_SDIO.h"
+	#endif
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_PCIE.c b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_PCIE.c
new file mode 100644
index 000000000..04927bf1e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_PCIE.c
@@ -0,0 +1,101 @@
+/****************************************************************************** 
+* 
+* 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 
+* 
+* 
+******************************************************************************/
+
+//#include "Mp_Precomp.h"
+//#include "../odm_precomp.h"
+
+#include <drv_types.h>
+#include "HalEfuseMask8703B_PCIE.h"
+
+
+/******************************************************************************
+*                           MPCIE.TXT
+******************************************************************************/
+
+u1Byte Array_MP_8703B_MPCIE[] = { 
+		0xFF,
+		0xF3,
+		0x00,
+		0x0E,
+		0x70,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x07,
+		0xF3,
+		0xFF,
+		0xFF,
+		0xFF,
+		0xFF,
+		0xFF,
+		0xF1,
+		0x00,
+		0x80,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+
+};
+
+u2Byte
+EFUSE_GetArrayLen_MP_8703B_MPCIE(VOID)
+{
+	return sizeof(Array_MP_8703B_MPCIE)/sizeof(u1Byte);
+}
+
+VOID
+EFUSE_GetMaskArray_MP_8703B_MPCIE(
+	IN 	OUT pu1Byte Array
+	)
+{
+	u2Byte len = EFUSE_GetArrayLen_MP_8703B_MPCIE(), i = 0;
+
+	for (i = 0; i < len; ++i)
+	   Array[i] = Array_MP_8703B_MPCIE[i];
+}
+BOOLEAN
+EFUSE_IsAddressMasked_MP_8703B_MPCIE(
+ 	IN   u2Byte  Offset
+ 	)
+{
+	int r = Offset/16;
+	int c = (Offset%16) / 2;
+	int result = 0;
+
+	if (c < 4) // Upper double word
+	    result = (Array_MP_8703B_MPCIE[r] & (0x10 << c));
+	else
+	    result = (Array_MP_8703B_MPCIE[r] & (0x01 << (c-4)));
+
+	return (result > 0) ? 0 : 1;
+}
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_PCIE.h b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_PCIE.h
new file mode 100644
index 000000000..4497ddac2
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_PCIE.h
@@ -0,0 +1,40 @@
+/****************************************************************************** 
+* 
+* 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 
+* 
+* 
+******************************************************************************/
+
+
+/******************************************************************************
+*                           MPCIE.TXT
+******************************************************************************/
+
+
+u2Byte
+EFUSE_GetArrayLen_MP_8703B_MPCIE(VOID);
+
+VOID
+EFUSE_GetMaskArray_MP_8703B_MPCIE(
+	IN 	OUT pu1Byte Array
+);
+
+BOOLEAN
+EFUSE_IsAddressMasked_MP_8703B_MPCIE( // TC: Test Chip, MP: MP Chip
+	IN   u2Byte  Offset
+);
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_SDIO.c b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_SDIO.c
new file mode 100644
index 000000000..37ee7c66d
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_SDIO.c
@@ -0,0 +1,102 @@
+/****************************************************************************** 
+* 
+* 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 
+* 
+* 
+******************************************************************************/
+
+//#include "Mp_Precomp.h"
+//#include "../odm_precomp.h"
+
+#include <drv_types.h>
+#include "HalEfuseMask8703B_SDIO.h"
+
+
+
+/******************************************************************************
+*                           MSDIO.TXT
+******************************************************************************/
+
+u1Byte Array_MP_8703B_MSDIO[] = { 
+		0xFF,
+		0xF3,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x0F,
+		0xF1,
+		0xFF,
+		0xFF,
+		0xFF,
+		0xFF,
+		0xFF,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+
+};
+
+u2Byte
+EFUSE_GetArrayLen_MP_8703B_MSDIO(VOID)
+{
+	return sizeof(Array_MP_8703B_MSDIO)/sizeof(u1Byte);
+}
+
+VOID
+EFUSE_GetMaskArray_MP_8703B_MSDIO(
+	IN 	OUT pu1Byte Array
+	)
+{
+	u2Byte len = EFUSE_GetArrayLen_MP_8703B_MSDIO(), i = 0;
+
+	for (i = 0; i < len; ++i)
+	   Array[i] = Array_MP_8703B_MSDIO[i];
+}
+BOOLEAN
+EFUSE_IsAddressMasked_MP_8703B_MSDIO(
+ 	IN   u2Byte  Offset
+ 	)
+{
+	int r = Offset/16;
+	int c = (Offset%16) / 2;
+	int result = 0;
+
+	if (c < 4) // Upper double word
+	    result = (Array_MP_8703B_MSDIO[r] & (0x10 << c));
+	else
+	    result = (Array_MP_8703B_MSDIO[r] & (0x01 << (c-4)));
+
+	return (result > 0) ? 0 : 1;
+}
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_SDIO.h b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_SDIO.h
new file mode 100644
index 000000000..d624088b5
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_SDIO.h
@@ -0,0 +1,41 @@
+/****************************************************************************** 
+* 
+* 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 
+* 
+* 
+******************************************************************************/
+
+
+
+/******************************************************************************
+*                           MSDIO.TXT
+******************************************************************************/
+
+
+u2Byte
+EFUSE_GetArrayLen_MP_8703B_MSDIO(VOID);
+
+VOID
+EFUSE_GetMaskArray_MP_8703B_MSDIO(
+	IN 	OUT pu1Byte Array
+);
+
+BOOLEAN
+EFUSE_IsAddressMasked_MP_8703B_MSDIO( // TC: Test Chip, MP: MP Chip
+	IN   u2Byte  Offset
+);
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_USB.c b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_USB.c
new file mode 100644
index 000000000..937741eea
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_USB.c
@@ -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 
+* 
+* 
+******************************************************************************/
+
+//#include "Mp_Precomp.h"
+//#include "../odm_precomp.h"
+
+#include <drv_types.h>
+#include "HalEfuseMask8703B_USB.h"
+/******************************************************************************
+*                           MUSB.TXT
+******************************************************************************/
+
+u1Byte Array_MP_8703B_MUSB[] = { 
+		0xFF,
+		0xF3,
+		0x00,
+		0x0E,
+		0x70,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x07,
+		0xF1,
+		0x00,
+		0x00,
+		0x00,
+		0xFF,
+		0xFF,
+		0xFF,
+		0xFF,
+		0xB0,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+		0x00,
+
+};
+
+u2Byte
+EFUSE_GetArrayLen_MP_8703B_MUSB(VOID)
+{
+	return sizeof(Array_MP_8703B_MUSB)/sizeof(u1Byte);
+}
+
+VOID
+EFUSE_GetMaskArray_MP_8703B_MUSB(
+	IN 	OUT pu1Byte Array
+	)
+{
+	u2Byte len = EFUSE_GetArrayLen_MP_8703B_MUSB(), i = 0;
+
+	for (i = 0; i < len; ++i)
+	   Array[i] = Array_MP_8703B_MUSB[i];
+}
+BOOLEAN
+EFUSE_IsAddressMasked_MP_8703B_MUSB(
+ 	IN   u2Byte  Offset
+ 	)
+{
+	int r = Offset/16;
+	int c = (Offset%16) / 2;
+	int result = 0;
+
+	if (c < 4) // Upper double word
+	    result = (Array_MP_8703B_MUSB[r] & (0x10 << c));
+	else
+	    result = (Array_MP_8703B_MUSB[r] & (0x01 << (c-4)));
+
+	return (result > 0) ? 0 : 1;
+}
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_USB.h b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_USB.h
new file mode 100644
index 000000000..a3330650a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/efuse/rtl8703b/HalEfuseMask8703B_USB.h
@@ -0,0 +1,42 @@
+/****************************************************************************** 
+* 
+* 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 
+* 
+* 
+******************************************************************************/
+
+
+
+/******************************************************************************
+*                           MUSB.TXT
+******************************************************************************/
+
+
+u2Byte
+EFUSE_GetArrayLen_MP_8703B_MUSB(VOID);
+
+VOID
+EFUSE_GetMaskArray_MP_8703B_MUSB(
+	IN 	OUT pu1Byte Array
+);
+
+BOOLEAN
+EFUSE_IsAddressMasked_MP_8703B_MUSB( // TC: Test Chip, MP: MP Chip
+	IN   u2Byte  Offset
+);
+
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_btcoex.c b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_btcoex.c
new file mode 100644
index 000000000..41dd4967e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_btcoex.c
@@ -0,0 +1,4044 @@
+/******************************************************************************
+ *
+ * Copyright(c) 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
+ *
+ *
+ ******************************************************************************/
+#define __HAL_BTCOEX_C__
+
+#ifdef CONFIG_BT_COEXIST
+
+#include <hal_data.h>
+#include <hal_btcoex.h>
+#include <Mp_Precomp.h>
+
+//====================================
+//		Global variables
+//====================================
+const char *const BtProfileString[] =
+{
+	"NONE",
+	"A2DP",
+	"PAN",
+	"HID",
+	"SCO",
+};
+
+const char *const BtSpecString[] =
+{
+	"1.0b",
+	"1.1",
+	"1.2",
+	"2.0+EDR",
+	"2.1+EDR",
+	"3.0+HS",
+	"4.0",
+};
+
+const char *const BtLinkRoleString[] =
+{
+	"Master",
+	"Slave",
+};
+
+const char *const h2cStaString[] =
+{
+	"successful",
+	"h2c busy",
+	"rf off",
+	"fw not read",
+};
+
+const char *const ioStaString[] =
+{
+	"success",
+	"can not IO",
+	"rf off",
+	"fw not read",
+	"wait io timeout",
+	"invalid len",
+	"idle Q empty",
+	"insert waitQ fail",
+	"unknown fail",
+	"wrong level",
+	"h2c stopped",
+};
+
+const char *const GLBtcWifiBwString[]={
+	"11bg",
+	"HT20",
+	"HT40",
+	"HT80",
+	"HT160"
+};
+
+const char *const GLBtcWifiFreqString[]={
+	"2.4G",
+	"5G"
+};
+
+const char *const GLBtcIotPeerString[] = {
+	"UNKNOWN",
+	"REALTEK",
+	"REALTEK_92SE",
+	"BROADCOM",
+	"RALINK",
+	"ATHEROS",
+	"CISCO",
+	"MERU",	
+	"MARVELL",
+	"REALTEK_SOFTAP", /* peer is RealTek SOFT_AP, by Bohn, 2009.12.17 */
+	"SELF_SOFTAP", /* Self is SoftAP */
+	"AIRGO",
+	"INTEL", 
+	"RTK_APCLIENT", 
+	"REALTEK_81XX",	
+	"REALTEK_WOW",
+	"REALTEK_JAGUAR_BCUTAP",
+	"REALTEK_JAGUAR_CCUTAP"
+};
+
+const char *const coexOpcodeString[] = {
+	"Wifi status notify",
+	"Wifi progress",
+	"Wifi info",
+	"Power state",
+	"Set Control",
+	"Get Control"
+};
+
+const char *const coexIndTypeString[] = {
+	"bt info",
+	"pstdma",
+	"limited tx/rx",
+	"coex table",
+	"request"
+};
+
+const char *const coexH2cResultString[] = {
+	"ok",
+	"unknown",
+	"un opcode",
+	"opVer MM",
+	"par Err",
+	"par OoR",
+	"reqNum MM",
+	"halMac Fail",
+	"h2c TimeOut",
+	"Invalid c2h Len",
+	"data overflow"
+};
+
+#define HALBTCOUTSRC_AGG_CHK_WINDOW_IN_MS	8000
+
+struct btc_coexist GLBtCoexist;
+BTC_OFFLOAD gl_coex_offload;
+u8 GLBtcWiFiInScanState;
+u8 GLBtcWiFiInIQKState;
+u8 GLBtcWiFiInIPS;
+u8 GLBtcWiFiInLPS;
+u8 GLBtcBtCoexAliveRegistered;
+
+/*
+ * BT control H2C/C2H
+ */
+/* EXT_EID */
+typedef enum _bt_ext_eid {
+	C2H_WIFI_FW_ACTIVE_RSP	= 0,
+	C2H_TRIG_BY_BT_FW
+} BT_EXT_EID;
+
+/* C2H_STATUS */
+typedef enum _bt_c2h_status {
+	BT_STATUS_OK = 0,
+	BT_STATUS_VERSION_MISMATCH,
+	BT_STATUS_UNKNOWN_OPCODE,
+	BT_STATUS_ERROR_PARAMETER
+} BT_C2H_STATUS;
+
+/* C2H BT OP CODES */
+typedef enum _bt_op_code {
+	BT_OP_GET_BT_VERSION	= 0,
+	BT_OP_WRITE_REG_ADDR	= 12,
+	BT_OP_WRITE_REG_VALUE,
+	BT_OP_READ_REG		= 17
+} BT_OP_CODE;
+
+#define BTC_MPOPER_TIMEOUT	50	/* unit: ms */
+
+#define C2H_MAX_SIZE		16
+u8 GLBtcBtMpOperSeq;
+_mutex GLBtcBtMpOperLock;
+_timer GLBtcBtMpOperTimer;
+_sema GLBtcBtMpRptSema;
+u8 GLBtcBtMpRptSeq;
+u8 GLBtcBtMpRptStatus;
+u8 GLBtcBtMpRptRsp[C2H_MAX_SIZE];
+u8 GLBtcBtMpRptRspSize;
+u8 GLBtcBtMpRptWait;
+u8 GLBtcBtMpRptWiFiOK;
+u8 GLBtcBtMpRptBTOK;
+
+/*
+ * Debug
+ */
+u32 GLBtcDbgType[COMP_MAX];
+u8 GLBtcDbgBuf[BT_TMP_BUF_SIZE];
+u1Byte	gl_btc_trace_buf[BT_TMP_BUF_SIZE];
+
+typedef struct _btcoexdbginfo
+{
+	u8 *info;
+	u32 size; // buffer total size
+	u32 len; // now used length
+} BTCDBGINFO, *PBTCDBGINFO;
+
+BTCDBGINFO GLBtcDbgInfo;
+
+#define	BT_Operation(Adapter)						_FALSE
+
+static void DBG_BT_INFO_INIT(PBTCDBGINFO pinfo, u8 *pbuf, u32 size)
+{
+	if (NULL == pinfo) return;
+
+	_rtw_memset(pinfo, 0, sizeof(BTCDBGINFO));
+
+	if (pbuf && size) {
+		pinfo->info = pbuf;
+		pinfo->size = size;
+	}
+}
+
+void DBG_BT_INFO(u8 *dbgmsg)
+{
+	PBTCDBGINFO pinfo;
+	u32 msglen, buflen;
+	u8 *pbuf;
+
+
+	pinfo = &GLBtcDbgInfo;
+
+	if (NULL == pinfo->info)
+		return;
+
+	msglen = strlen(dbgmsg);
+	if (pinfo->len + msglen > pinfo->size)
+		return;
+
+	pbuf = pinfo->info + pinfo->len;
+	_rtw_memcpy(pbuf, dbgmsg, msglen);
+	pinfo->len += msglen;
+}
+
+//====================================
+//		Debug related function
+//====================================
+static u8 halbtcoutsrc_IsBtCoexistAvailable(PBTC_COEXIST pBtCoexist)
+{
+	if (!pBtCoexist->bBinded ||
+		NULL == pBtCoexist->Adapter)
+	{
+		return _FALSE;
+	}
+	return _TRUE;
+}
+
+static void halbtcoutsrc_DbgInit(void)
+{
+	u8	i;
+
+	for (i = 0; i < COMP_MAX; i++)
+		GLBtcDbgType[i] = 0;
+}
+
+static u8 halbtcoutsrc_IsCsrBtCoex(PBTC_COEXIST pBtCoexist)
+{
+	if (pBtCoexist->board_info.bt_chip_type == BTC_CHIP_CSR_BC4
+		|| pBtCoexist->board_info.bt_chip_type == BTC_CHIP_CSR_BC8
+	){
+		return _TRUE;
+	}
+	return _FALSE;
+}
+
+static u8 halbtcoutsrc_IsHwMailboxExist(PBTC_COEXIST pBtCoexist)
+{
+	if (pBtCoexist->board_info.bt_chip_type == BTC_CHIP_CSR_BC4
+		|| pBtCoexist->board_info.bt_chip_type == BTC_CHIP_CSR_BC8
+	){
+		return _FALSE;
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		return _FALSE;
+	}
+	else
+		return _TRUE;
+}
+
+static void halbtcoutsrc_LeaveLps(PBTC_COEXIST pBtCoexist)
+{
+	PADAPTER padapter;
+
+
+	padapter = pBtCoexist->Adapter;
+
+	pBtCoexist->btInfo.bBtCtrlLps = _TRUE;
+	pBtCoexist->btInfo.bBtLpsOn = _FALSE;
+
+	rtw_btcoex_LPS_Leave(padapter);
+}
+
+void halbtcoutsrc_EnterLps(PBTC_COEXIST pBtCoexist)
+{
+	PADAPTER padapter;
+
+
+	padapter = pBtCoexist->Adapter;
+
+	pBtCoexist->btInfo.bBtCtrlLps = _TRUE;
+	pBtCoexist->btInfo.bBtLpsOn = _TRUE;
+
+	rtw_btcoex_LPS_Enter(padapter);
+}
+
+void halbtcoutsrc_NormalLps(PBTC_COEXIST pBtCoexist)
+{
+	PADAPTER padapter;
+
+
+	RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Normal LPS behavior!!!\n"));
+
+	padapter = pBtCoexist->Adapter;
+
+	if (pBtCoexist->btInfo.bBtCtrlLps)
+	{
+		pBtCoexist->btInfo.bBtLpsOn = _FALSE;
+		rtw_btcoex_LPS_Leave(padapter);
+		pBtCoexist->btInfo.bBtCtrlLps = _FALSE;
+
+		// recover the LPS state to the original
+#if 0
+		padapter->HalFunc.UpdateLPSStatusHandler(
+			padapter,
+			pPSC->RegLeisurePsMode,
+			pPSC->RegPowerSaveMode);
+#endif
+	}
+}
+
+/*
+ *  Constraint:
+ *	   1. this function will request pwrctrl->lock
+ */
+void halbtcoutsrc_LeaveLowPower(PBTC_COEXIST pBtCoexist)
+{
+#ifdef CONFIG_LPS_LCLK
+	PADAPTER padapter;
+	PHAL_DATA_TYPE pHalData;
+	struct pwrctrl_priv *pwrctrl;
+	s32 ready;
+	u32 stime;
+	s32 utime;
+	u32 timeout; // unit: ms
+
+
+	padapter = pBtCoexist->Adapter;
+	pHalData = GET_HAL_DATA(padapter);
+	pwrctrl = adapter_to_pwrctl(padapter);
+	ready = _FAIL;
+#ifdef LPS_RPWM_WAIT_MS
+	timeout = LPS_RPWM_WAIT_MS;
+#else // !LPS_RPWM_WAIT_MS
+	timeout = 30;
+#endif // !LPS_RPWM_WAIT_MS
+
+	if (GLBtcBtCoexAliveRegistered == _TRUE)
+		return;
+
+	stime = rtw_get_current_time();
+	do {
+		ready = rtw_register_task_alive(padapter, BTCOEX_ALIVE);
+		if (_SUCCESS == ready)
+			break;
+
+		utime = rtw_get_passing_time_ms(stime);
+		if (utime > timeout)
+			break;
+
+		rtw_msleep_os(1);
+	} while (1);
+
+	GLBtcBtCoexAliveRegistered = _TRUE;
+#endif // CONFIG_LPS_LCLK
+}
+
+/*
+ *  Constraint:
+ *	   1. this function will request pwrctrl->lock
+ */
+void halbtcoutsrc_NormalLowPower(PBTC_COEXIST pBtCoexist)
+{
+#ifdef CONFIG_LPS_LCLK
+	PADAPTER padapter;
+
+	if (GLBtcBtCoexAliveRegistered == _FALSE)
+		return;
+
+	padapter = pBtCoexist->Adapter;
+	rtw_unregister_task_alive(padapter, BTCOEX_ALIVE);
+
+	GLBtcBtCoexAliveRegistered = _FALSE;
+#endif // CONFIG_LPS_LCLK
+}
+
+void halbtcoutsrc_DisableLowPower(PBTC_COEXIST pBtCoexist, u8 bLowPwrDisable)
+{
+	pBtCoexist->btInfo.bBtDisableLowPwr = bLowPwrDisable;
+	if (bLowPwrDisable)
+		halbtcoutsrc_LeaveLowPower(pBtCoexist);		// leave 32k low power.
+	else
+		halbtcoutsrc_NormalLowPower(pBtCoexist);	// original 32k low power behavior.
+}
+
+void halbtcoutsrc_AggregationCheck(PBTC_COEXIST pBtCoexist)
+{
+	PADAPTER padapter;
+	BOOLEAN bNeedToAct = _FALSE;
+	static u32 preTime = 0;
+	u32 curTime = 0;
+
+	padapter = pBtCoexist->Adapter;
+
+	//=====================================
+	// To void continuous deleteBA=>addBA=>deleteBA=>addBA
+	// This function is not allowed to continuous called.
+	// It can only be called after 8 seconds.
+	//=====================================
+
+	curTime = rtw_systime_to_ms(rtw_get_current_time());
+	if((curTime - preTime) < HALBTCOUTSRC_AGG_CHK_WINDOW_IN_MS)	// over 8 seconds you can execute this function again.
+	{
+		return;
+	}
+	else
+	{
+		preTime = curTime;
+	}
+
+	if (pBtCoexist->btInfo.bRejectAggPkt)
+	{
+		bNeedToAct = _TRUE;
+		pBtCoexist->btInfo.bPreRejectAggPkt = pBtCoexist->btInfo.bRejectAggPkt;
+	}
+	else
+	{
+		if(pBtCoexist->btInfo.bPreRejectAggPkt)
+		{
+			bNeedToAct = _TRUE;
+			pBtCoexist->btInfo.bPreRejectAggPkt = pBtCoexist->btInfo.bRejectAggPkt;
+		}
+		
+		if (pBtCoexist->btInfo.bPreBtCtrlAggBufSize !=
+			pBtCoexist->btInfo.bBtCtrlAggBufSize)
+		{
+			bNeedToAct = _TRUE;
+			pBtCoexist->btInfo.bPreBtCtrlAggBufSize = pBtCoexist->btInfo.bBtCtrlAggBufSize;
+		}
+
+		if (pBtCoexist->btInfo.bBtCtrlAggBufSize)
+		{
+			if (pBtCoexist->btInfo.preAggBufSize !=
+				pBtCoexist->btInfo.aggBufSize)
+			{
+				bNeedToAct = _TRUE;
+			}
+			pBtCoexist->btInfo.preAggBufSize = pBtCoexist->btInfo.aggBufSize;
+		}
+	}
+
+	if (bNeedToAct)
+		rtw_btcoex_rx_ampdu_apply(padapter);
+}
+
+u8 halbtcoutsrc_IsWifiBusy(PADAPTER padapter)
+{
+	struct mlme_priv *pmlmepriv;
+
+
+	pmlmepriv = &padapter->mlmepriv;
+
+	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
+	{
+		if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
+			return _TRUE;
+		if (_TRUE == pmlmepriv->LinkDetectInfo.bBusyTraffic)
+			return _TRUE;
+	}
+
+#if defined(CONFIG_CONCURRENT_MODE)
+	pmlmepriv = &padapter->pbuddy_adapter->mlmepriv;
+
+	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
+	{
+		if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
+			return _TRUE;
+		if (_TRUE == pmlmepriv->LinkDetectInfo.bBusyTraffic)
+			return _TRUE;
+	}
+#endif
+
+	return _FALSE;
+}
+
+static u32 _halbtcoutsrc_GetWifiLinkStatus(PADAPTER padapter)
+{
+	struct mlme_priv *pmlmepriv;
+	u8 bp2p;
+	u32 portConnectedStatus;
+
+
+	pmlmepriv = &padapter->mlmepriv;
+	bp2p = _FALSE;
+	portConnectedStatus = 0;
+
+#ifdef CONFIG_P2P
+	if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
+		bp2p = _TRUE;
+#endif // CONFIG_P2P
+
+	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
+	{
+		if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
+		{
+			if (_TRUE == bp2p)
+				portConnectedStatus |= WIFI_P2P_GO_CONNECTED;
+			else
+				portConnectedStatus |= WIFI_AP_CONNECTED;
+		}
+		else
+		{
+			if (_TRUE == bp2p)
+				portConnectedStatus |= WIFI_P2P_GC_CONNECTED;
+			else
+				portConnectedStatus |= WIFI_STA_CONNECTED;
+		}
+	}
+
+	return portConnectedStatus;
+}
+
+u32 halbtcoutsrc_GetWifiLinkStatus(PBTC_COEXIST pBtCoexist)
+{
+	//=================================
+	// return value:
+	// [31:16]=> connected port number
+	// [15:0]=> port connected bit define
+	//================================
+
+	PADAPTER padapter;
+	u32 retVal;
+	u32 portConnectedStatus, numOfConnectedPort;
+
+
+	padapter = pBtCoexist->Adapter;
+	retVal = 0;
+	portConnectedStatus = 0;
+	numOfConnectedPort = 0;
+
+	retVal = _halbtcoutsrc_GetWifiLinkStatus(padapter);
+	if (retVal)
+	{
+		portConnectedStatus |= retVal;
+		numOfConnectedPort++;
+	}
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->pbuddy_adapter)
+	{
+		retVal = _halbtcoutsrc_GetWifiLinkStatus(padapter->pbuddy_adapter);
+		if (retVal)
+		{
+			portConnectedStatus |= retVal;
+			numOfConnectedPort++;
+		}
+	}
+#endif // CONFIG_CONCURRENT_MODE
+
+	retVal = (numOfConnectedPort << 16) | portConnectedStatus;
+	
+	return retVal;
+}
+
+static u8 _is_btfwver_valid(PBTC_COEXIST pBtCoexist, u16 btfwver)
+{
+	if (!btfwver)
+		return _FALSE;
+
+	if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+		if (btfwver == 0x8723)
+			return _FALSE;
+
+	return _TRUE;
+}
+
+static void _btmpoper_timer_hdl(struct timer_list *t)
+{
+	if (GLBtcBtMpRptWait) {
+		GLBtcBtMpRptWait = 0;
+		_rtw_up_sema(&GLBtcBtMpRptSema);
+	}
+}
+
+/*
+ * !IMPORTANT!
+ *	Before call this function, caller should acquire "GLBtcBtMpOperLock"!
+ *	Othrewise there will be racing problem and something may go wrong.
+ */
+static u8 _btmpoper_cmd(PBTC_COEXIST pBtCoexist, u8 opcode, u8 opcodever, u8 *cmd, u8 size)
+{
+	PADAPTER padapter;
+	u8 buf[H2C_BTMP_OPER_LEN] = {0};
+	u8 buflen;
+	u8 seq;
+	u8 timer_cancelled;
+	s32 ret;
+
+
+	if (!cmd && size)
+		size = 0;
+	if ((size + 2) > H2C_BTMP_OPER_LEN)
+		return BT_STATUS_H2C_LENGTH_EXCEEDED;
+	buflen = size + 2;
+
+	seq = GLBtcBtMpOperSeq & 0xF;
+	GLBtcBtMpOperSeq++;
+
+	buf[0] = (opcodever & 0xF) | (seq << 4);
+	buf[1] = opcode;
+	if (cmd && size)
+		_rtw_memcpy(buf+2, cmd, size);
+
+	GLBtcBtMpRptWait = 1;
+	GLBtcBtMpRptWiFiOK = 0;
+	GLBtcBtMpRptBTOK = 0;
+	GLBtcBtMpRptStatus = 0;
+	padapter = pBtCoexist->Adapter;
+	_set_timer(&GLBtcBtMpOperTimer, BTC_MPOPER_TIMEOUT);
+	if (rtw_hal_fill_h2c_cmd(padapter, H2C_BT_MP_OPER, buflen, buf) == _FAIL) {
+		_cancel_timer(&GLBtcBtMpOperTimer, &timer_cancelled);
+		ret = BT_STATUS_H2C_FAIL;
+		goto exit;
+	}
+
+	_rtw_down_sema(&GLBtcBtMpRptSema);
+	/* GLBtcBtMpRptWait should be 0 here*/
+
+	if (!GLBtcBtMpRptWiFiOK) {
+		DBG_871X("%s: Didn't get H2C Rsp Event!\n", __FUNCTION__);
+		ret = BT_STATUS_H2C_TIMTOUT;
+		goto exit;
+	}
+	if (!GLBtcBtMpRptBTOK) {
+		DBG_871X("%s: Didn't get BT response!\n", __FUNCTION__);
+		ret = BT_STATUS_H2C_BT_NO_RSP;
+		goto exit;
+	}
+	if (seq != GLBtcBtMpRptSeq) {
+		DBG_871X("%s: Sequence number not match!(%d!=%d)!\n",
+			__FUNCTION__, seq, GLBtcBtMpRptSeq);
+		ret = BT_STATUS_C2H_REQNUM_MISMATCH;
+		goto exit;
+	}
+
+	switch (GLBtcBtMpRptStatus) {
+	/* Examine the status reported from C2H */
+	case BT_STATUS_OK:
+		ret = BT_STATUS_BT_OP_SUCCESS;
+		DBG_871X("%s: C2H status = BT_STATUS_BT_OP_SUCCESS\n", __FUNCTION__);
+		break;
+	case BT_STATUS_VERSION_MISMATCH:
+		ret = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
+		DBG_871X("%s: C2H status = BT_STATUS_OPCODE_L_VERSION_MISMATCH\n", __FUNCTION__);
+		break;
+	case BT_STATUS_UNKNOWN_OPCODE:
+		ret = BT_STATUS_UNKNOWN_OPCODE_L;
+		DBG_871X("%s: C2H status = MP_BT_STATUS_UNKNOWN_OPCODE_L\n", __FUNCTION__);
+		break;
+	case BT_STATUS_ERROR_PARAMETER:
+		ret = BT_STATUS_PARAMETER_FORMAT_ERROR_L;
+		DBG_871X("%s: C2H status = MP_BT_STATUS_PARAMETER_FORMAT_ERROR_L\n", __FUNCTION__);
+		break;
+	default:
+		ret = BT_STATUS_UNKNOWN_STATUS_L;
+		DBG_871X("%s: C2H status = MP_BT_STATUS_UNKNOWN_STATUS_L\n", __FUNCTION__);
+		break;
+	}
+
+exit:
+	return ret;
+}
+
+u32 halbtcoutsrc_GetBtPatchVer(PBTC_COEXIST pBtCoexist)
+{
+	if (_is_btfwver_valid(pBtCoexist, pBtCoexist->btInfo.btRealFwVer) == _TRUE)
+		goto exit;
+
+	if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == _TRUE) {
+		_irqL irqL;
+		u8 ret;
+
+
+		_enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+		ret = _btmpoper_cmd(pBtCoexist, BT_OP_GET_BT_VERSION, 0, NULL, 0);
+		if (BT_STATUS_BT_OP_SUCCESS == ret) {
+			pBtCoexist->btInfo.btRealFwVer = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp);
+			pBtCoexist->btInfo.btFwVer = *(GLBtcBtMpRptRsp+2);
+		}
+		pBtCoexist->btInfo.getBtFwVerCnt++;
+
+		_exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+	} else {
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+		u1Byte dataLen = 2;
+		u1Byte buf[4] = {0};
+
+		buf[0] = 0x0;	/* OP_Code */
+		buf[1] = 0x0;	/* OP_Code_Length */
+		BT_SendEventExtBtCoexControl(pBtCoexist->Adapter, _FALSE, dataLen, &buf[0]);
+#endif /* !CONFIG_BT_COEXIST_SOCKET_TRX */
+	}
+
+exit:
+	return pBtCoexist->btInfo.btRealFwVer;
+}
+
+s32 halbtcoutsrc_GetWifiRssi(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	s32 UndecoratedSmoothedPWDB = 0;
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	UndecoratedSmoothedPWDB = pHalData->EntryMinUndecoratedSmoothedPWDB;
+
+	return UndecoratedSmoothedPWDB;
+}
+
+static u8 halbtcoutsrc_GetWifiScanAPNum(PADAPTER padapter)
+{
+	struct mlme_priv *pmlmepriv;
+	struct mlme_ext_priv *pmlmeext;
+	static u8 scan_AP_num = 0;
+
+
+	pmlmepriv = &padapter->mlmepriv;
+	pmlmeext = &padapter->mlmeextpriv;
+
+	if (GLBtcWiFiInScanState == _FALSE) {
+		if (pmlmepriv->num_of_scanned > 0xFF)
+			scan_AP_num = 0xFF;
+		else
+			scan_AP_num = (u8)pmlmepriv->num_of_scanned;
+	}
+
+	return scan_AP_num;
+}
+
+u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+	PHAL_DATA_TYPE pHalData;
+	struct mlme_ext_priv *mlmeext;
+	u8 bSoftApExist, bVwifiExist;
+	u8 *pu8;
+	s32 *pS4Tmp;
+	u32 *pU4Tmp;
+	u8 *pU1Tmp;
+	u8 ret;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return _FALSE;
+
+	padapter = pBtCoexist->Adapter;
+	pHalData = GET_HAL_DATA(padapter);
+	mlmeext = &padapter->mlmeextpriv;
+	bSoftApExist = _FALSE;
+	bVwifiExist = _FALSE;
+	pu8 = (u8*)pOutBuf;
+	pS4Tmp = (s32*)pOutBuf;
+	pU4Tmp = (u32*)pOutBuf;
+	pU1Tmp = (u8*)pOutBuf;
+	ret = _TRUE;
+
+	switch (getType)
+	{
+		case BTC_GET_BL_HS_OPERATION:
+			*pu8 = _FALSE;
+			ret = _FALSE;
+			break;
+
+		case BTC_GET_BL_HS_CONNECTING:
+			*pu8 = _FALSE;
+			ret = _FALSE;
+			break;
+
+		case BTC_GET_BL_WIFI_CONNECTED:
+			*pu8 = check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE);
+#ifdef CONFIG_CONCURRENT_MODE
+			if ((_FALSE == *pu8) && padapter->pbuddy_adapter)
+			{
+				*pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_ASOC_STATE);
+			}
+#endif // CONFIG_CONCURRENT_MODE
+			break;
+
+		case BTC_GET_BL_WIFI_BUSY:
+			*pu8 = halbtcoutsrc_IsWifiBusy(padapter);
+			break;
+
+		case BTC_GET_BL_WIFI_SCAN:
+#if 0			
+			*pu8 = check_fwstate(&padapter->mlmepriv, WIFI_SITE_MONITOR);
+#ifdef CONFIG_CONCURRENT_MODE
+			if ((_FALSE == *pu8) && padapter->pbuddy_adapter)
+			{
+				*pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_SITE_MONITOR);
+			}
+#endif // CONFIG_CONCURRENT_MODE
+#else		
+			/* Use the value of the new variable GLBtcWiFiInScanState to judge whether WiFi is in scan state or not, since the originally used flag 
+				WIFI_SITE_MONITOR in fwstate may not be cleared in time */
+			*pu8 = GLBtcWiFiInScanState;
+#endif
+			break;
+
+		case BTC_GET_BL_WIFI_LINK:
+			*pu8 = check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING);
+#ifdef CONFIG_CONCURRENT_MODE
+			if ((_FALSE == *pu8) && padapter->pbuddy_adapter)
+			{
+				*pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_UNDER_LINKING);
+			}
+#endif // CONFIG_CONCURRENT_MODE
+			break;
+
+		case BTC_GET_BL_WIFI_ROAM:
+			*pu8 = check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING);
+#ifdef CONFIG_CONCURRENT_MODE
+			if ((_FALSE == *pu8) && padapter->pbuddy_adapter)
+			{
+				*pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_UNDER_LINKING);
+			}
+#endif // CONFIG_CONCURRENT_MODE
+			break;
+
+		case BTC_GET_BL_WIFI_4_WAY_PROGRESS:
+			*pu8 = _FALSE;
+			break;
+
+		case BTC_GET_BL_WIFI_UNDER_5G:
+			*pu8 = (pHalData->CurrentBandType == 1)? _TRUE : _FALSE;
+			break;
+
+		case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
+			*pu8 = check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE);
+#ifdef CONFIG_CONCURRENT_MODE
+			if ((_FALSE == *pu8) && padapter->pbuddy_adapter)
+			{
+				*pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_AP_STATE);
+			}
+#endif // CONFIG_CONCURRENT_MODE
+			break;
+
+		case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
+			*pu8 = padapter->securitypriv.dot11PrivacyAlgrthm == 0? _FALSE: _TRUE;
+			break;
+
+		case BTC_GET_BL_WIFI_UNDER_B_MODE:
+			if (mlmeext->cur_wireless_mode == WIRELESS_11B)
+				*pu8 = _TRUE;
+			else
+				*pu8 = _FALSE;
+			break;
+
+		case BTC_GET_BL_WIFI_IS_IN_MP_MODE:
+			if (padapter->registrypriv.mp_mode == 0)
+			{
+				*pu8 = _FALSE;
+			}
+			else
+			{
+				*pu8 = _TRUE;
+			}
+			break;
+
+		case BTC_GET_BL_EXT_SWITCH:
+			*pu8 = _FALSE;
+			break;
+		case BTC_GET_BL_IS_ASUS_8723B:
+			/* Always return FALSE in linux driver since this case is added only for windows driver */
+			*pu8 = _FALSE;
+			break;
+
+		case BTC_GET_S4_WIFI_RSSI:
+			*pS4Tmp = halbtcoutsrc_GetWifiRssi(padapter);
+			break;
+
+		case BTC_GET_S4_HS_RSSI:
+			*pS4Tmp = 0;
+			ret = _FALSE;
+			break;
+
+		case BTC_GET_U4_WIFI_BW:
+			if (IsLegacyOnly(mlmeext->cur_wireless_mode))
+				*pU4Tmp = BTC_WIFI_BW_LEGACY;
+			else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_20)
+				*pU4Tmp = BTC_WIFI_BW_HT20;
+			else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40)
+				*pU4Tmp = BTC_WIFI_BW_HT40;
+			else
+				*pU4Tmp = BTC_WIFI_BW_HT40; /* todo */
+			break;
+
+		case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION:
+			{
+				PRT_LINK_DETECT_T plinkinfo;
+				plinkinfo = &padapter->mlmepriv.LinkDetectInfo;
+
+				if (plinkinfo->NumTxOkInPeriod > plinkinfo->NumRxOkInPeriod)
+					*pU4Tmp = BTC_WIFI_TRAFFIC_TX;
+				else
+					*pU4Tmp = BTC_WIFI_TRAFFIC_RX;
+			}
+			break;
+
+		case BTC_GET_U4_WIFI_FW_VER:
+			*pU4Tmp = pHalData->FirmwareVersion << 16;
+			*pU4Tmp |= pHalData->FirmwareSubVersion;
+			break;
+
+		case BTC_GET_U4_WIFI_LINK_STATUS:
+			*pU4Tmp = halbtcoutsrc_GetWifiLinkStatus(pBtCoexist);
+			break;
+
+		case BTC_GET_U4_BT_PATCH_VER:
+			*pU4Tmp = halbtcoutsrc_GetBtPatchVer(pBtCoexist);
+			break;
+
+		case BTC_GET_U4_VENDOR:
+			*pU4Tmp = BTC_VENDOR_OTHER;
+			break;
+
+		case BTC_GET_U1_WIFI_DOT11_CHNL:
+			*pU1Tmp = padapter->mlmeextpriv.cur_channel;
+			break;
+
+		case BTC_GET_U1_WIFI_CENTRAL_CHNL:
+			*pU1Tmp = pHalData->CurrentChannel;
+			break;
+
+		case BTC_GET_U1_WIFI_HS_CHNL:
+			*pU1Tmp = 0;
+			ret = _FALSE;
+			break;
+
+		case BTC_GET_U1_MAC_PHY_MODE:
+//			*pU1Tmp = BTC_SMSP;
+//			*pU1Tmp = BTC_DMSP;
+//			*pU1Tmp = BTC_DMDP;
+//			*pU1Tmp = BTC_MP_UNKNOWN;
+			break;
+
+		case BTC_GET_U1_AP_NUM:
+			*pU1Tmp = halbtcoutsrc_GetWifiScanAPNum(padapter);
+			break;
+		case BTC_GET_U1_ANT_TYPE:
+			switch(pHalData->bt_coexist.btAntisolation)
+			{
+				case 0:
+					*pU1Tmp = (u1Byte)BTC_ANT_TYPE_0;
+					pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_0;
+					break;
+				case 1:
+					*pU1Tmp = (u1Byte)BTC_ANT_TYPE_1;
+					pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_1;
+					break;
+				case 2:
+					*pU1Tmp = (u1Byte)BTC_ANT_TYPE_2;
+					pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_2;
+					break;
+				case 3:
+					*pU1Tmp = (u1Byte)BTC_ANT_TYPE_3;
+					pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_3;
+					break;
+				case 4:
+					*pU1Tmp = (u1Byte)BTC_ANT_TYPE_4;
+					pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_4;
+					break;
+			}
+			break;
+		case BTC_GET_U1_IOT_PEER:
+			*pU1Tmp = mlmeext->mlmext_info.assoc_AP_vendor;
+			break;
+
+		//=======1Ant===========
+		case BTC_GET_U1_LPS_MODE:
+			*pU1Tmp = padapter->dvobj->pwrctl_priv.pwr_mode;
+			break;
+
+		default:
+			ret = _FALSE;
+			break;
+	}
+
+	return ret;
+}
+
+u8 halbtcoutsrc_Set(void *pBtcContext, u8 setType, void *pInBuf)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+	PHAL_DATA_TYPE pHalData;
+	u8 *pu8;
+	u8 *pU1Tmp;
+	u32	*pU4Tmp;
+	u8 ret;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+	pHalData = GET_HAL_DATA(padapter);
+	pu8 = (u8*)pInBuf;
+	pU1Tmp = (u8*)pInBuf;
+	pU4Tmp = (u32*)pInBuf;
+	ret = _TRUE;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return _FALSE;
+
+	switch (setType)
+	{
+		// set some u8 type variables.
+		case BTC_SET_BL_BT_DISABLE:
+			pBtCoexist->btInfo.bBtDisabled = *pu8;
+			break;
+
+		case BTC_SET_BL_BT_TRAFFIC_BUSY:
+			pBtCoexist->btInfo.bBtBusy = *pu8;
+			break;
+
+		case BTC_SET_BL_BT_LIMITED_DIG:
+			pBtCoexist->btInfo.bLimitedDig = *pu8;
+			break;
+
+		case BTC_SET_BL_FORCE_TO_ROAM:
+			pBtCoexist->btInfo.bForceToRoam = *pu8;
+			break;
+
+		case BTC_SET_BL_TO_REJ_AP_AGG_PKT:
+			pBtCoexist->btInfo.bRejectAggPkt = *pu8;
+			break;
+
+		case BTC_SET_BL_BT_CTRL_AGG_SIZE:
+			pBtCoexist->btInfo.bBtCtrlAggBufSize = *pu8;
+			break;
+
+		case BTC_SET_BL_INC_SCAN_DEV_NUM:
+			pBtCoexist->btInfo.bIncreaseScanDevNum = *pu8;
+			break;
+
+		case BTC_SET_BL_BT_TX_RX_MASK:
+			pBtCoexist->btInfo.bBtTxRxMask = *pu8;
+			break;
+
+		case BTC_SET_BL_MIRACAST_PLUS_BT:
+			pBtCoexist->btInfo.bMiracastPlusBt = *pu8;
+			break;
+
+		// set some u8 type variables.
+		case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON:
+			pBtCoexist->btInfo.rssiAdjustForAgcTableOn = *pU1Tmp;
+			break;
+
+		case BTC_SET_U1_AGG_BUF_SIZE:
+			pBtCoexist->btInfo.aggBufSize = *pU1Tmp;
+			break;
+
+		// the following are some action which will be triggered
+		case BTC_SET_ACT_GET_BT_RSSI:
+#if 0
+			BT_SendGetBtRssiEvent(padapter);
+#else
+			ret = _FALSE;
+#endif
+			break;
+
+		case BTC_SET_ACT_AGGREGATE_CTRL:
+			halbtcoutsrc_AggregationCheck(pBtCoexist);
+			break;
+
+		//=======1Ant===========
+		// set some u8 type variables.
+		case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE:
+			pBtCoexist->btInfo.rssiAdjustFor1AntCoexType = *pU1Tmp;
+			break;
+
+		case BTC_SET_U1_LPS_VAL:
+			pBtCoexist->btInfo.lpsVal = *pU1Tmp;
+			break;
+
+		case BTC_SET_U1_RPWM_VAL:
+			pBtCoexist->btInfo.rpwmVal = *pU1Tmp;
+			break;
+
+		// the following are some action which will be triggered
+		case BTC_SET_ACT_LEAVE_LPS:
+			halbtcoutsrc_LeaveLps(pBtCoexist);
+			break;
+
+		case BTC_SET_ACT_ENTER_LPS:
+			halbtcoutsrc_EnterLps(pBtCoexist);
+			break;
+
+		case BTC_SET_ACT_NORMAL_LPS:
+			halbtcoutsrc_NormalLps(pBtCoexist);
+			break;
+
+		case BTC_SET_ACT_DISABLE_LOW_POWER:
+			halbtcoutsrc_DisableLowPower(pBtCoexist, *pu8);
+			break;
+
+		case BTC_SET_ACT_UPDATE_RAMASK:
+			pBtCoexist->btInfo.raMask = *pU4Tmp;
+
+			if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
+			{
+				struct sta_info *psta;
+				PWLAN_BSSID_EX cur_network;
+
+				cur_network = &padapter->mlmeextpriv.mlmext_info.network;
+				psta = rtw_get_stainfo(&padapter->stapriv, cur_network->MacAddress);
+				rtw_hal_update_ra_mask(psta, 0);
+			}
+			break;
+
+		case BTC_SET_ACT_SEND_MIMO_PS:
+			{
+				u8 newMimoPsMode = 3;
+				struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+				struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+				/* *pU1Tmp = 0 use SM_PS static type */
+				/* *pU1Tmp = 1 disable SM_PS */
+				if (*pU1Tmp == 0)
+					newMimoPsMode = WLAN_HT_CAP_SM_PS_STATIC;
+				else if (*pU1Tmp == 1)
+					newMimoPsMode = WLAN_HT_CAP_SM_PS_DISABLED;
+												  
+				if (check_fwstate(&padapter->mlmepriv , WIFI_ASOC_STATE) == _TRUE) {
+					/* issue_action_SM_PS(padapter, get_my_bssid(&(pmlmeinfo->network)), newMimoPsMode); */
+					issue_action_SM_PS_wait_ack(padapter , get_my_bssid(&(pmlmeinfo->network)) , newMimoPsMode, 3 , 1);
+				}
+			}
+			break;
+
+		case BTC_SET_ACT_CTRL_BT_INFO:
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+			{
+				u8 dataLen = *pU1Tmp;
+				u8 tmpBuf[BTC_TMP_BUF_SHORT];
+				if (dataLen)
+				{
+					_rtw_memcpy(tmpBuf, pU1Tmp+1, dataLen);
+				}
+				BT_SendEventExtBtInfoControl(padapter, dataLen, &tmpBuf[0]);
+			}
+#else //!CONFIG_BT_COEXIST_SOCKET_TRX
+			ret = _FALSE;
+#endif //CONFIG_BT_COEXIST_SOCKET_TRX
+			break;
+
+		case BTC_SET_ACT_CTRL_BT_COEX:
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+			{
+				u8 dataLen = *pU1Tmp;
+				u8 tmpBuf[BTC_TMP_BUF_SHORT];
+				if (dataLen)
+				{
+					_rtw_memcpy(tmpBuf, pU1Tmp+1, dataLen);
+				}
+				BT_SendEventExtBtCoexControl(padapter, _FALSE, dataLen, &tmpBuf[0]);
+			}
+#else //!CONFIG_BT_COEXIST_SOCKET_TRX
+			ret = _FALSE;
+#endif //CONFIG_BT_COEXIST_SOCKET_TRX
+			break;
+		case BTC_SET_ACT_CTRL_8723B_ANT:
+#if 0
+			{
+				u1Byte	dataLen=*pU1Tmp;
+				u1Byte	tmpBuf[BTC_TMP_BUF_SHORT];
+				if(dataLen)
+				{
+					PlatformMoveMemory(&tmpBuf[0], pU1Tmp+1, dataLen);
+				}
+				BT_Set8723bAnt(Adapter, dataLen, &tmpBuf[0]);
+			}
+#else
+			ret = _FALSE;
+#endif
+			break;
+		//=====================
+		default:
+			ret = _FALSE;
+			break;
+	}
+
+	return ret;
+}
+
+u8 halbtcoutsrc_UnderIps(PBTC_COEXIST pBtCoexist)
+{
+	PADAPTER padapter;
+	struct pwrctrl_priv *pwrpriv;
+	u8 bMacPwrCtrlOn;
+
+	padapter = pBtCoexist->Adapter;
+	pwrpriv = &padapter->dvobj->pwrctl_priv;
+	bMacPwrCtrlOn = _FALSE;
+
+	if ((_TRUE == pwrpriv->bips_processing)
+		&& (IPS_NONE != pwrpriv->ips_mode_req)
+		)
+	{
+		return _TRUE;
+	}
+
+	if (rf_off == pwrpriv->rf_pwrstate)
+	{
+		return _TRUE;
+	}
+
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if (_FALSE == bMacPwrCtrlOn)
+	{
+		return _TRUE;
+	}
+
+	return _FALSE;
+}
+
+u8 halbtcoutsrc_UnderLps(PBTC_COEXIST pBtCoexist)
+{
+	return GLBtcWiFiInLPS;
+}
+
+u8 halbtcoutsrc_Under32K(PBTC_COEXIST pBtCoexist)
+{
+	/* todo: the method to check whether wifi is under 32K or not */
+	return _FALSE;
+}
+
+void halbtcoutsrc_DisplayCoexStatistics(PBTC_COEXIST pBtCoexist)
+{
+#if 0
+	PADAPTER padapter = (PADAPTER)pBtCoexist->Adapter;
+	PBT_MGNT pBtMgnt = &padapter->MgntInfo.BtInfo.BtMgnt;
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	u8 *cliBuf = pBtCoexist->cliBuf;
+	u1Byte			i, j;
+	u1Byte			tmpbuf[BTC_TMP_BUF_SHORT];
+
+
+	if (gl_coex_offload.cnt_h2c_sent) {
+		CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Coex h2c notify]============");
+		CL_PRINTF(cliBuf);
+
+		CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = H2c(%d)/Ack(%d)", "Coex h2c/c2h overall statistics",
+			gl_coex_offload.cnt_h2c_sent, gl_coex_offload.cnt_c2h_ack);
+		for (j = 0; j < COL_STATUS_MAX; j++) {
+			if (gl_coex_offload.status[j]) {
+				CL_SPRINTF(tmpbuf, BTC_TMP_BUF_SHORT, ", %s:%d", coexH2cResultString[j], gl_coex_offload.status[j]);
+				CL_STRNCAT(cliBuf, BT_TMP_BUF_SIZE, tmpbuf, BTC_TMP_BUF_SHORT);
+			}
+		}
+		CL_PRINTF(cliBuf);
+	}
+	for (i = 0; i < COL_OP_WIFI_OPCODE_MAX; i++) {
+		if (gl_coex_offload.h2c_record[i].count) {
+			/*==========================================*/
+			/*	H2C result statistics*/
+			/*==========================================*/
+			CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = total:%d", coexOpcodeString[i], gl_coex_offload.h2c_record[i].count);
+			for (j = 0; j < COL_STATUS_MAX; j++) {
+				if (gl_coex_offload.h2c_record[i].status[j]) {
+					CL_SPRINTF(tmpbuf, BTC_TMP_BUF_SHORT, ", %s:%d", coexH2cResultString[j], gl_coex_offload.h2c_record[i].status[j]);
+					CL_STRNCAT(cliBuf, BT_TMP_BUF_SIZE, tmpbuf, BTC_TMP_BUF_SHORT);
+				}
+			}
+			CL_PRINTF(cliBuf);
+			/*==========================================*/
+			/*	H2C/C2H content*/
+			/*==========================================*/
+			CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = ", "H2C / C2H content");
+			for (j = 0; j < gl_coex_offload.h2c_record[i].h2c_len; j++) {
+				CL_SPRINTF(tmpbuf, BTC_TMP_BUF_SHORT, "%02x ", gl_coex_offload.h2c_record[i].h2c_buf[j]);
+				CL_STRNCAT(cliBuf, BT_TMP_BUF_SIZE, tmpbuf, 3);
+			}
+			if (gl_coex_offload.h2c_record[i].c2h_ack_len) {
+				CL_STRNCAT(cliBuf, BT_TMP_BUF_SIZE, "/ ", 2);
+				for (j = 0; j < gl_coex_offload.h2c_record[i].c2h_ack_len; j++) {
+					CL_SPRINTF(tmpbuf, BTC_TMP_BUF_SHORT, "%02x ", gl_coex_offload.h2c_record[i].c2h_ack_buf[j]);
+					CL_STRNCAT(cliBuf, BT_TMP_BUF_SIZE, tmpbuf, 3);
+				}
+			}
+			CL_PRINTF(cliBuf);
+			/*==========================================*/
+		}
+	}
+
+	if (gl_coex_offload.cnt_c2h_ind) {
+		CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Coex c2h indication]============");
+		CL_PRINTF(cliBuf);
+
+		CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = Ind(%d)", "C2H indication statistics",
+			gl_coex_offload.cnt_c2h_ind);
+		for (j = 0; j < COL_STATUS_MAX; j++) {
+			if (gl_coex_offload.c2h_ind_status[j]) {
+				CL_SPRINTF(tmpbuf, BTC_TMP_BUF_SHORT, ", %s:%d", coexH2cResultString[j], gl_coex_offload.c2h_ind_status[j]);
+				CL_STRNCAT(cliBuf, BT_TMP_BUF_SIZE, tmpbuf, BTC_TMP_BUF_SHORT);
+			}
+		}
+		CL_PRINTF(cliBuf);
+	}
+	for (i = 0; i < COL_IND_MAX; i++) {
+		if (gl_coex_offload.c2h_ind_record[i].count) {
+			/*==========================================*/
+			/*	H2C result statistics*/
+			/*==========================================*/
+			CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = total:%d", coexIndTypeString[i], gl_coex_offload.c2h_ind_record[i].count);
+			for (j = 0; j < COL_STATUS_MAX; j++) {
+				if (gl_coex_offload.c2h_ind_record[i].status[j]) {
+					CL_SPRINTF(tmpbuf, BTC_TMP_BUF_SHORT, ", %s:%d", coexH2cResultString[j], gl_coex_offload.c2h_ind_record[i].status[j]);
+					CL_STRNCAT(cliBuf, BT_TMP_BUF_SIZE, tmpbuf, BTC_TMP_BUF_SHORT);
+				}
+			}
+			CL_PRINTF(cliBuf);
+			/*==========================================*/
+			/*	content*/
+			/*==========================================*/
+			CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = ", "C2H indication content");
+			for (j = 0; j < gl_coex_offload.c2h_ind_record[i].ind_len; j++) {
+				CL_SPRINTF(tmpbuf, BTC_TMP_BUF_SHORT, "%02x ", gl_coex_offload.c2h_ind_record[i].ind_buf[j]);
+				CL_STRNCAT(cliBuf, BT_TMP_BUF_SIZE, tmpbuf, 3);
+			}
+			CL_PRINTF(cliBuf);
+			/*==========================================*/
+		}
+	}
+
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Statistics]============");
+	CL_PRINTF(cliBuf);
+
+#if (H2C_USE_IO_THREAD != 1)
+	for(i=0; i<H2C_STATUS_MAX; i++)
+	{
+		if (pHalData->h2cStatistics[i])
+		{
+			CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s] = %d", "H2C statistics", \
+				h2cStaString[i], pHalData->h2cStatistics[i]);
+			CL_PRINTF(cliBuf);
+		}
+	}
+#else
+		for(i=0; i<IO_STATUS_MAX; i++)
+		{
+			if(Adapter->ioComStr.ioH2cStatistics[i])
+			{
+				CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s] = %d", "H2C statistics", \
+					ioStaString[i], Adapter->ioComStr.ioH2cStatistics[i]);
+				CL_PRINTF(cliBuf);
+			}
+		}
+#endif
+#if 0
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "lastHMEBoxNum", \
+		pHalData->LastHMEBoxNum);
+	CL_PRINTF(cliBuf);
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x / 0x%x", "LastOkH2c/FirstFailH2c(fwNotRead)", \
+		pHalData->lastSuccessH2cEid, pHalData->firstFailedH2cEid);
+	CL_PRINTF(cliBuf);
+
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "c2hIsr/c2hIntr/clr1AF/noRdy/noBuf", \
+		pHalData->InterruptLog.nIMR_C2HCMD, DBG_Var.c2hInterruptCnt, DBG_Var.c2hClrReadC2hCnt,
+		DBG_Var.c2hNotReadyCnt, DBG_Var.c2hBufAlloFailCnt);
+	CL_PRINTF(cliBuf);
+
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "c2hPacket", \
+		DBG_Var.c2hPacketCnt);
+	CL_PRINTF(cliBuf);
+#endif
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Periodical/ DbgCtrl", \
+		pBtCoexist->statistics.cntPeriodical, pBtCoexist->statistics.cntDbgCtrl);
+	CL_PRINTF(cliBuf);
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", "PowerOn/InitHw/InitCoexDm/RfStatus", \
+		pBtCoexist->statistics.cntPowerOn, pBtCoexist->statistics.cntInitHwConfig, pBtCoexist->statistics.cntInitCoexDm,
+		pBtCoexist->statistics.cntRfStatusNotify);
+	CL_PRINTF(cliBuf);
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "Ips/Lps/Scan/Connect/Mstatus", \
+		pBtCoexist->statistics.cntIpsNotify, pBtCoexist->statistics.cntLpsNotify,
+		pBtCoexist->statistics.cntScanNotify, pBtCoexist->statistics.cntConnectNotify,
+		pBtCoexist->statistics.cntMediaStatusNotify);
+	CL_PRINTF(cliBuf);
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d", "Special pkt/Bt info/ bind", 
+		pBtCoexist->statistics.cntSpecialPacketNotify, pBtCoexist->statistics.cntBtInfoNotify,
+		pBtCoexist->statistics.cntBind);
+	CL_PRINTF(cliBuf);
+#endif
+}
+
+void halbtcoutsrc_DisplayBtLinkInfo(PBTC_COEXIST pBtCoexist)
+{
+#if 0
+	PADAPTER padapter = (PADAPTER)pBtCoexist->Adapter;
+	PBT_MGNT pBtMgnt = &padapter->MgntInfo.BtInfo.BtMgnt;
+	u8 *cliBuf = pBtCoexist->cliBuf;
+	u8 i;
+
+
+	if (pBtCoexist->stack_info.profile_notified)
+	{
+		for (i=0; i<pBtMgnt->ExtConfig.NumberOfACL; i++)
+		{
+			if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1)
+			{
+				CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "Bt link type/spec/role", \
+					BtProfileString[pBtMgnt->ExtConfig.aclLink[i].BTProfile],
+					BtSpecString[pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec],
+					BtLinkRoleString[pBtMgnt->ExtConfig.aclLink[i].linkRole]);
+				CL_PRINTF(cliBuf);				}
+			else
+			{
+				CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", "Bt link type/spec", \
+					BtProfileString[pBtMgnt->ExtConfig.aclLink[i].BTProfile],
+					BtSpecString[pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec]);
+				CL_PRINTF(cliBuf);
+			}
+		}
+	}
+#endif
+}
+
+void halbtcoutsrc_DisplayWifiStatus(PBTC_COEXIST pBtCoexist)
+{
+	PADAPTER	padapter = pBtCoexist->Adapter;
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+	u8			*cliBuf = pBtCoexist->cli_buf;
+	s32			wifiRssi=0, btHsRssi=0;
+	BOOLEAN	bScan=_FALSE, bLink=_FALSE, bRoam=_FALSE, bWifiBusy=_FALSE, bWifiUnderBMode=_FALSE;
+	u32			wifiBw=BTC_WIFI_BW_HT20, wifiTrafficDir=BTC_WIFI_TRAFFIC_TX, wifiFreq=BTC_FREQ_2_4G;
+	u32			wifiLinkStatus=0x0;
+	BOOLEAN	bBtHsOn=_FALSE, bLowPower=_FALSE;
+	u8			wifiChnl=0, wifiHsChnl=0, nScanAPNum = 0, FwPSState;
+
+	wifiLinkStatus = halbtcoutsrc_GetWifiLinkStatus(pBtCoexist);
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "STA/vWifi/HS/p2pGo/p2pGc", \
+		((wifiLinkStatus&WIFI_STA_CONNECTED)? 1:0), ((wifiLinkStatus&WIFI_AP_CONNECTED)? 1:0), 
+		((wifiLinkStatus&WIFI_HS_CONNECTED)? 1:0), ((wifiLinkStatus&WIFI_P2P_GO_CONNECTED)? 1:0), 
+		((wifiLinkStatus&WIFI_P2P_GC_CONNECTED)? 1:0) );
+	CL_PRINTF(cliBuf);
+
+	if (wifiLinkStatus&WIFI_STA_CONNECTED) {
+		CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "IOT Peer", GLBtcIotPeerString[padapter->mlmeextpriv.mlmext_info.assoc_AP_vendor]);
+		CL_PRINTF(cliBuf);
+	}
+
+	pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+	pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiChnl);
+	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(High Speed)",
+		wifiChnl, wifiHsChnl, bBtHsOn);
+	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-100, btHsRssi-100);
+	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, &wifiFreq);
+	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);
+	pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode);
+	pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_AP_NUM, &nScanAPNum);
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s/ AP=%d ", "Wifi freq/ bw/ traffic", \
+		GLBtcWifiFreqString[wifiFreq], ((bWifiUnderBMode)? "11b": GLBtcWifiBwString[wifiBw]),
+		((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink")), 
+		nScanAPNum);
+	CL_PRINTF(cliBuf);
+
+	// power status
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s%s%s", "Power Status", \
+		((halbtcoutsrc_UnderIps(pBtCoexist) == _TRUE)? "IPS ON":"IPS OFF"),
+		((halbtcoutsrc_UnderLps(pBtCoexist) == _TRUE)? ", LPS ON":", LPS OFF"), 
+		((halbtcoutsrc_Under32K(pBtCoexist) == _TRUE)? ", 32k":""));
+	CL_PRINTF(cliBuf);
+
+	CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x (0x%x/0x%x)", "Power mode cmd(lps/rpwm)", \
+		pBtCoexist->pwrModeVal[0], pBtCoexist->pwrModeVal[1],
+		pBtCoexist->pwrModeVal[2], pBtCoexist->pwrModeVal[3],
+		pBtCoexist->pwrModeVal[4], pBtCoexist->pwrModeVal[5],
+		pBtCoexist->btInfo.lpsVal, 
+		pBtCoexist->btInfo.rpwmVal);
+	CL_PRINTF(cliBuf);
+}
+
+void halbtcoutsrc_DisplayDbgMsg(void *pBtcContext, u8 dispType)
+{
+	PBTC_COEXIST pBtCoexist;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	switch(dispType)
+	{
+		case BTC_DBG_DISP_COEX_STATISTICS:
+			halbtcoutsrc_DisplayCoexStatistics(pBtCoexist);
+			break;
+		case BTC_DBG_DISP_BT_LINK_INFO:
+			halbtcoutsrc_DisplayBtLinkInfo(pBtCoexist);
+			break;
+		case BTC_DBG_DISP_WIFI_STATUS:
+			halbtcoutsrc_DisplayWifiStatus(pBtCoexist);
+			break;
+		default:
+			break;
+	}
+}
+
+//====================================
+//		IO related function
+//====================================
+u8 halbtcoutsrc_Read1Byte(void *pBtcContext, u32 RegAddr)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	return rtw_read8(padapter, RegAddr);
+}
+
+u16 halbtcoutsrc_Read2Byte(void *pBtcContext, u32 RegAddr)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	return	rtw_read16(padapter, RegAddr);
+}
+
+u32 halbtcoutsrc_Read4Byte(void *pBtcContext, u32 RegAddr)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	return	rtw_read32(padapter, RegAddr);
+}
+
+void halbtcoutsrc_Write1Byte(void *pBtcContext, u32 RegAddr, u8 Data)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	rtw_write8(padapter, RegAddr, Data);
+}
+
+void halbtcoutsrc_BitMaskWrite1Byte(void *pBtcContext, u32 regAddr, u8 bitMask, u8 data1b)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+	u8 originalValue, bitShift;
+	u8 i;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+	originalValue = 0;
+	bitShift = 0;
+
+	if(bitMask != 0xff)
+	{
+		originalValue = rtw_read8(padapter, regAddr);
+
+		for (i=0; i<=7; i++)
+		{
+			if ((bitMask>>i)&0x1)
+				break;
+		}
+		bitShift = i;
+
+		data1b = (originalValue & ~bitMask) | ((data1b << bitShift) & bitMask);
+	}
+
+	rtw_write8(padapter, regAddr, data1b);
+}
+
+void halbtcoutsrc_Write2Byte(void *pBtcContext, u32 RegAddr, u16 Data)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	rtw_write16(padapter, RegAddr, Data);
+}
+
+void halbtcoutsrc_Write4Byte(void *pBtcContext, u32 RegAddr, u32 Data)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	rtw_write32(padapter, RegAddr, Data);
+}
+
+void halbtcoutsrc_WriteLocalReg1Byte(void *pBtcContext, u32 RegAddr, u8 Data)
+{
+	PBTC_COEXIST		pBtCoexist=(PBTC_COEXIST)pBtcContext;
+	PADAPTER			Adapter=pBtCoexist->Adapter;
+
+	if (BTC_INTF_SDIO == pBtCoexist->chip_interface)
+		rtw_write8(Adapter, SDIO_LOCAL_BASE | RegAddr, Data);
+	else
+		rtw_write8(Adapter, RegAddr, Data);
+}
+
+void halbtcoutsrc_SetBbReg(void *pBtcContext, u32 RegAddr, u32 BitMask, u32 Data)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	PHY_SetBBReg(padapter, RegAddr, BitMask, Data);
+}
+
+
+u32 halbtcoutsrc_GetBbReg(void *pBtcContext, u32 RegAddr, u32 BitMask)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	return PHY_QueryBBReg(padapter, RegAddr, BitMask);
+}
+
+void halbtcoutsrc_SetRfReg(void *pBtcContext, u8 eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	PHY_SetRFReg(padapter, eRFPath, RegAddr, BitMask, Data);
+}
+
+u32 halbtcoutsrc_GetRfReg(void *pBtcContext, u8 eRFPath, u32 RegAddr, u32 BitMask)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	return PHY_QueryRFReg(padapter, eRFPath, RegAddr, BitMask);
+}
+
+u16 halbtcoutsrc_SetBtReg(void *pBtcContext, u8 RegType, u32 RegAddr, u32 Data)
+{
+	PBTC_COEXIST pBtCoexist;
+	u16 ret = BT_STATUS_BT_OP_SUCCESS;
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+
+	if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == _TRUE) {
+		u8 buf[3] = {0};
+		_irqL irqL;
+		u8 op_code;
+		u8 status;
+
+		_enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+		Data = cpu_to_le32(Data);
+		op_code = BT_OP_WRITE_REG_VALUE;
+		status = _btmpoper_cmd(pBtCoexist, op_code, 0, (u8 *)&Data, 3);
+		if (status != BT_STATUS_BT_OP_SUCCESS)
+			ret = SET_BT_MP_OPER_RET(op_code, status);
+		else {
+			buf[0] = RegType;
+			*(u16 *)(buf+1) = cpu_to_le16((u16)RegAddr);
+			op_code = BT_OP_WRITE_REG_ADDR;
+			status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 3);
+			if (status != BT_STATUS_BT_OP_SUCCESS)
+				ret = SET_BT_MP_OPER_RET(op_code, status);
+		}
+
+		_exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+	} else
+		ret = BT_STATUS_NOT_IMPLEMENT;
+
+	return ret;
+}
+
+u8 halbtcoutsrc_SetBtAntDetection(void *pBtcContext, u8 txTime, u8 btChnl)
+{
+/* Always return _FALSE since we don't implement this yet */	
+#if 0	
+	PBTC_COEXIST		pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	PADAPTER			Adapter = pBtCoexist->Adapter;
+	u1Byte				btCanTx = 0;
+	BOOLEAN			bStatus = FALSE;
+
+	bStatus = NDBG_SetBtAntDetection(Adapter, txTime, btChnl, &btCanTx);
+	if (bStatus && btCanTx)
+		return _TRUE;
+	else
+		return _FALSE;
+#else
+	return _FALSE;
+#endif
+}
+
+u16 halbtcoutsrc_GetBtReg(void *pBtcContext, u8 RegType, u32 RegAddr, u32 *data)
+{
+	PBTC_COEXIST pBtCoexist;
+	u16 ret = BT_STATUS_BT_OP_SUCCESS;
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+
+	if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == _TRUE) {
+		u8 buf[3] = {0};
+		_irqL irqL;
+		u8 op_code;
+		u8 status;
+
+		buf[0] = RegType;
+		*(u16 *)(buf+1) = cpu_to_le16((u16)RegAddr);
+
+		_enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+		op_code = BT_OP_READ_REG;
+		status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 3);
+		if (status == BT_STATUS_BT_OP_SUCCESS)
+			*data = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp);
+		else
+			ret = SET_BT_MP_OPER_RET(op_code, status);
+
+		_exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+	} else
+		ret = BT_STATUS_NOT_IMPLEMENT;
+
+	return ret;
+}
+
+void halbtcoutsrc_FillH2cCmd(void *pBtcContext, u8 elementId, u32 cmdLen, u8 *pCmdBuffer)
+{
+	PBTC_COEXIST pBtCoexist;
+	PADAPTER padapter;
+
+
+	pBtCoexist = (PBTC_COEXIST)pBtcContext;
+	padapter = pBtCoexist->Adapter;
+
+	rtw_hal_fill_h2c_cmd(padapter, elementId, cmdLen, pCmdBuffer);
+}
+
+static void halbtcoutsrc_coex_offload_init(void)
+{
+	u1Byte	i;
+
+	gl_coex_offload.h2c_req_num = 0;
+	gl_coex_offload.cnt_h2c_sent = 0;
+	gl_coex_offload.cnt_c2h_ack = 0;
+	gl_coex_offload.cnt_c2h_ind = 0;
+
+	for (i = 0; i < COL_MAX_H2C_REQ_NUM; i++)
+		init_completion(&gl_coex_offload.c2h_event[i]);
+}
+
+static COL_H2C_STATUS halbtcoutsrc_send_h2c(PADAPTER Adapter, PCOL_H2C pcol_h2c, u16 h2c_cmd_len)
+{
+	COL_H2C_STATUS		h2c_status = COL_STATUS_C2H_OK;
+	u8				i;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+	reinit_completion(&gl_coex_offload.c2h_event[pcol_h2c->req_num]);		/* set event to un signaled state */
+#else
+	INIT_COMPLETION(gl_coex_offload.c2h_event[pcol_h2c->req_num]);
+#endif
+
+	if (TRUE) {
+#if 0	/*(USE_HAL_MAC_API==1) */
+		if (RT_STATUS_SUCCESS == HAL_MAC_Send_BT_COEX(&GET_HAL_MAC_INFO(Adapter), (pu1Byte)(pcol_h2c), (u4Byte)h2c_cmd_len, 1)) {
+			RT_TRACE(COMP_COEX, DBG_LOUD, ("HAL_MAC_Send_BT_COEX successfully.\n"));
+			if (wait_for_completion_timeout(&gl_coex_offload.c2h_event[pcol_h2c->req_num], 20)) {
+				RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], received H2C rsp event!!\n"));
+			} else {
+				RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], H2C timeout!!\n"));
+				h2c_status = COL_STATUS_H2C_TIMTOUT;
+			}
+		} else {
+			RT_TRACE(COMP_COEX, DBG_LOUD, ("HAL_MAC_Send_BT_COEX fail.\n"));
+			h2c_status = COL_STATUS_H2C_HALMAC_FAIL;
+		}
+#endif
+	}
+
+	return h2c_status;
+}
+
+static COL_H2C_STATUS halbtcoutsrc_check_c2h_ack(PADAPTER Adapter, PCOL_SINGLE_H2C_RECORD pH2cRecord)
+{
+	COL_H2C_STATUS	c2h_status = COL_STATUS_C2H_OK;
+	PCOL_H2C		p_h2c_cmd = (PCOL_H2C)&pH2cRecord->h2c_buf[0];
+	u8			req_num = p_h2c_cmd->req_num;
+	PCOL_C2H_ACK	p_c2h_ack = (PCOL_C2H_ACK)&gl_coex_offload.c2h_ack_buf[req_num];
+
+	RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], c2h ack len=%d, coex return len=%d!!!\n",
+		gl_coex_offload.c2h_ack_len[req_num], p_c2h_ack->ret_len));
+
+	if ((COL_C2H_ACK_HDR_LEN+p_c2h_ack->ret_len) > gl_coex_offload.c2h_ack_len[req_num]) {
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], coex data overflow!!!\n"));
+		c2h_status = COL_STATUS_COEX_DATA_OVERFLOW;
+		return c2h_status;
+	}
+	/* else */
+	{
+		_rtw_memmove(&pH2cRecord->c2h_ack_buf[0], &gl_coex_offload.c2h_ack_buf[req_num], gl_coex_offload.c2h_ack_len[req_num]);
+		pH2cRecord->c2h_ack_len = gl_coex_offload.c2h_ack_len[req_num];
+	}
+
+	RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], c2h ack: status=0x%x, opcode_ver=0x%x, req_num=%d, ret_len=%d\n",
+		p_c2h_ack->status, p_c2h_ack->opcode_ver, p_c2h_ack->req_num, p_c2h_ack->ret_len));
+
+	if (p_c2h_ack->req_num != p_h2c_cmd->req_num) {
+		c2h_status = COL_STATUS_C2H_REQ_NUM_MISMATCH;
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], Error!! C2H req_num Mismatch!!\n"));
+	} else if (p_c2h_ack->opcode_ver != p_h2c_cmd->opcode_ver) {
+		c2h_status = COL_STATUS_C2H_OPCODE_VER_MISMATCH;
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], Error!! OPCode version mismatch!!\n"));
+	} else {
+		c2h_status = p_c2h_ack->status;
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], status from fw = %d!!\n", c2h_status));
+	}
+
+	return c2h_status;
+}
+
+COL_H2C_STATUS halbtcoutsrc_CoexH2cProcess(void *pBtCoexist,
+				u8 opcode, u8 opcode_ver, u8 *ph2c_par, u8 h2c_par_len)
+{
+	PADAPTER			Adapter = ((struct btc_coexist *)pBtCoexist)->Adapter;
+	u8				H2C_Parameter[BTC_TMP_BUF_SHORT] = {0};
+	PCOL_H2C			pcol_h2c = (PCOL_H2C)&H2C_Parameter[0];
+	u16				paraLen = 0;
+	COL_H2C_STATUS		h2c_status = COL_STATUS_C2H_OK, c2h_status = COL_STATUS_C2H_OK;
+	COL_H2C_STATUS		ret_status = COL_STATUS_C2H_OK;
+	u16				i, col_h2c_len = 0;
+
+	pcol_h2c->opcode = opcode;
+	pcol_h2c->opcode_ver = opcode_ver;
+	pcol_h2c->req_num = gl_coex_offload.h2c_req_num;
+	gl_coex_offload.h2c_req_num++;
+	gl_coex_offload.h2c_req_num %= 16;
+
+	_rtw_memmove(&pcol_h2c->buf[0], ph2c_par, h2c_par_len);
+
+	RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], H2C opcode/ opcode_ver/ req_num/ h2c_par_len=%d/ %d/ %d/ %d\n",
+		pcol_h2c->opcode, pcol_h2c->opcode_ver, pcol_h2c->req_num, h2c_par_len));
+
+	col_h2c_len = h2c_par_len+2;	/* 2=sizeof(OPCode, OPCode_version and  Request number) */
+	BT_PrintData(Adapter, "[COL], H2C cmd: ", col_h2c_len, H2C_Parameter);
+
+	gl_coex_offload.cnt_h2c_sent++;
+
+	gl_coex_offload.h2c_record[opcode].count++;
+	gl_coex_offload.h2c_record[opcode].h2c_len = col_h2c_len;
+	_rtw_memmove((PVOID)&gl_coex_offload.h2c_record[opcode].h2c_buf[0], (PVOID)pcol_h2c, col_h2c_len);
+
+	h2c_status = halbtcoutsrc_send_h2c(Adapter, pcol_h2c, col_h2c_len);
+
+	gl_coex_offload.h2c_record[opcode].c2h_ack_len = 0;
+
+	if (COL_STATUS_C2H_OK == h2c_status) {
+		/* if reach here, it means H2C get the correct c2h response, */
+		c2h_status = halbtcoutsrc_check_c2h_ack(Adapter, &gl_coex_offload.h2c_record[opcode]);
+		ret_status = c2h_status;
+	} else {
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], H2C failed for opCode=%d\n", opcode));
+		/* check h2c status error, return error status code to upper layer. */
+		ret_status = h2c_status;
+	}
+	gl_coex_offload.h2c_record[opcode].status[ret_status]++;
+	gl_coex_offload.status[ret_status]++;
+
+	return ret_status;
+}
+
+#if 0
+static void BT_CoexOffloadRecordErrC2hAck(PADAPTER	Adapter)
+{
+	PADAPTER		pDefaultAdapter = GetDefaultAdapter(Adapter);
+
+	if (pDefaultAdapter != Adapter)
+		return;
+
+	if (!hal_btcoex_IsBtExist(Adapter))
+		return;
+
+	gl_coex_offload.cnt_c2h_ack++;
+
+	gl_coex_offload.status[COL_STATUS_INVALID_C2H_LEN]++;
+}
+
+static void BT_CoexOffloadC2hAckCheck(PADAPTER	Adapter, u8 *tmpBuf, u8 length)
+{
+	PADAPTER		pDefaultAdapter = GetDefaultAdapter(Adapter);
+	PCOL_C2H_ACK	p_c2h_ack = NULL;
+	u8			req_num = 0xff;
+
+	if (pDefaultAdapter != Adapter)
+		return;
+
+	if (!hal_btcoex_IsBtExist(Adapter))
+		return;
+
+	gl_coex_offload.cnt_c2h_ack++;
+
+	if (length < COL_C2H_ACK_HDR_LEN) {		/* c2h ack length must >= 3 (status, opcode_ver, req_num and ret_len) */
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], invalid c2h ack length (%d)!!!\n", length));
+		gl_coex_offload.status[COL_STATUS_INVALID_C2H_LEN]++;
+	} else {
+		BT_PrintData(Adapter, "[COL], c2h ack:", length, tmpBuf);
+
+		p_c2h_ack = (PCOL_C2H_ACK)tmpBuf;
+		req_num = p_c2h_ack->req_num;
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], req_num = %d!!!\n", req_num));
+
+		_rtw_memmove(&gl_coex_offload.c2h_ack_buf[req_num][0], tmpBuf, length);
+		gl_coex_offload.c2h_ack_len[req_num] = length;
+
+		complete(&gl_coex_offload.c2h_event[req_num]);
+	}
+}
+
+static void BT_CoexOffloadC2hIndCheck(PADAPTER Adapter, u8 *tmpBuf, u8 length)
+{
+	PADAPTER		pDefaultAdapter = GetDefaultAdapter(Adapter);
+	PCOL_C2H_IND	p_c2h_ind = NULL;
+	u8			ind_type = 0, ind_version = 0, ind_length = 0;
+
+	if (pDefaultAdapter != Adapter)
+		return;
+
+	if (!hal_btcoex_IsBtExist(Adapter))
+		return;
+
+	gl_coex_offload.cnt_c2h_ind++;
+
+	if (length < COL_C2H_IND_HDR_LEN) {		/* c2h indication length must >= 3 (type, version and length) */
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], invalid c2h indication length (%d)!!!\n", length));
+		gl_coex_offload.c2h_ind_status[COL_STATUS_INVALID_C2H_LEN]++;
+	} else {
+		BT_PrintData(Adapter, "[COL], c2h indication:", length, tmpBuf);
+
+		p_c2h_ind = (PCOL_C2H_IND)tmpBuf;
+		ind_type = p_c2h_ind->type;
+		ind_version = p_c2h_ind->version;
+		ind_length = p_c2h_ind->length;
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], type/ version/ length = %d/ %d/ %d!!!\n",
+			ind_type, ind_version, ind_length));
+
+		_rtw_memmove(&gl_coex_offload.c2h_ind_buf[0], tmpBuf, length);
+		gl_coex_offload.c2h_ind_len = length;
+
+		/* log */
+		gl_coex_offload.c2h_ind_record[ind_type].count++;
+		gl_coex_offload.c2h_ind_record[ind_type].status[COL_STATUS_C2H_OK]++;
+		_rtw_memmove(&gl_coex_offload.c2h_ind_record[ind_type].ind_buf[0], tmpBuf, length);
+		gl_coex_offload.c2h_ind_record[ind_type].ind_len = length;
+
+		gl_coex_offload.c2h_ind_status[COL_STATUS_C2H_OK]++;
+		/*TODO: need to check c2h indication length*/
+		/* TODO: Notification */
+	}
+}
+
+void BT_CoexOffloadC2hCheck(PADAPTER Adapter, u8 *Buffer, u8 Length)
+{
+#if 0 /*(USE_HAL_MAC_API==1)*/
+	u8	c2hSubCmdId = 0, c2hAckLen = 0, h2cCmdId = 0, h2cSubCmdId = 0, c2hIndLen = 0;
+
+	BT_PrintData(Adapter, "[COL], c2h packet:", Length-2, Buffer+2);
+	c2hSubCmdId = (u1Byte)C2H_HDR_GET_C2H_SUB_CMD_ID(Buffer);
+	RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], c2hSubCmdId = 0x%x\n", c2hSubCmdId));
+
+	if (c2hSubCmdId == C2H_SUB_CMD_ID_H2C_ACK_HDR ||
+		c2hSubCmdId == C2H_SUB_CMD_ID_BT_COEX_INFO) {
+		if (c2hSubCmdId == C2H_SUB_CMD_ID_H2C_ACK_HDR) {
+			/* coex c2h ack */
+			h2cCmdId = (u1Byte)H2C_ACK_HDR_GET_H2C_CMD_ID(Buffer);
+			h2cSubCmdId = (u1Byte)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(Buffer);
+			RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], h2cCmdId/ h2cSubCmdId = 0x%x/ 0x%x\n", h2cCmdId, h2cSubCmdId));
+			if (h2cCmdId == 0xff && h2cSubCmdId == 0x60) {
+				c2hAckLen = (u1Byte)C2H_HDR_GET_LEN(Buffer);
+				RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], c2hAckLen = 0x%x\n", c2hAckLen));
+				if (c2hAckLen >= 8)
+					BT_CoexOffloadC2hAckCheck(Adapter, &Buffer[12], (u1Byte)(c2hAckLen-8));
+				else
+					BT_CoexOffloadRecordErrC2hAck(Adapter);
+			}
+		} else if (c2hSubCmdId == C2H_SUB_CMD_ID_BT_COEX_INFO) {
+			/* coex c2h indication */
+			c2hIndLen = (u1Byte)C2H_HDR_GET_LEN(Buffer);
+			RT_TRACE(COMP_COEX, DBG_LOUD, ("[COL], c2hAckLen = 0x%x\n", c2hIndLen));
+			BT_CoexOffloadC2hIndCheck(Adapter, &Buffer[4], (u1Byte)c2hIndLen);
+		}
+	}
+#endif
+}
+#endif
+
+//====================================
+//		Extern functions called by other module
+//====================================
+u8 EXhalbtcoutsrc_IsTfbgaPackageType(PADAPTER padapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+#ifdef CONFIG_RTL8723B
+	if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA80)
+		|| (pHalData->PackageType == PACKAGE_TFBGA90)) {
+		return _TRUE;
+	}		
+#endif
+
+	return _FALSE;
+}
+
+u8 EXhalbtcoutsrc_BindBtCoexWithAdapter(void *padapter)
+{
+	PBTC_COEXIST		pBtCoexist=&GLBtCoexist;
+	u1Byte	antNum=2, chipType;
+	
+	if(pBtCoexist->bBinded)
+		return _FALSE;
+	else
+		pBtCoexist->bBinded = _TRUE;
+
+	pBtCoexist->statistics.cntBind++;
+	
+	pBtCoexist->Adapter = padapter;
+	
+	pBtCoexist->stack_info.profile_notified = _FALSE;
+
+	pBtCoexist->btInfo.bBtCtrlAggBufSize = _FALSE;
+	pBtCoexist->btInfo.aggBufSize = 5;
+
+	pBtCoexist->btInfo.bIncreaseScanDevNum = _FALSE;
+	pBtCoexist->btInfo.bMiracastPlusBt = _FALSE;
+
+#if 0
+	chipType = HALBT_GetBtChipType(Adapter);
+	EXhalbtcoutsrc_SetChipType(chipType);
+	antNum = HALBT_GetPgAntNum(Adapter);
+	EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_PG, antNum);
+#endif
+	// set default antenna position to main  port
+	pBtCoexist->board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
+
+	pBtCoexist->board_info.btdm_ant_det_finish = _FALSE;
+	pBtCoexist->board_info.btdm_ant_num_by_ant_det = 1;
+
+	pBtCoexist->board_info.tfbga_package = EXhalbtcoutsrc_IsTfbgaPackageType((PADAPTER)padapter);
+
+	if (pBtCoexist->board_info.tfbga_package)
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Package Type = TFBGA\n"));
+	else
+		RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Package Type = Non-TFBGA\n"));
+	
+	return _TRUE;
+}
+
+u8 EXhalbtcoutsrc_InitlizeVariables(void *padapter)
+{
+	PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+	//pBtCoexist->statistics.cntBind++;
+
+	halbtcoutsrc_DbgInit();
+
+	halbtcoutsrc_coex_offload_init();
+
+#ifdef CONFIG_PCI_HCI
+	pBtCoexist->chip_interface = BTC_INTF_PCI;
+#elif defined(CONFIG_USB_HCI)
+	pBtCoexist->chip_interface = BTC_INTF_USB;
+#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+	pBtCoexist->chip_interface = BTC_INTF_SDIO;
+#else
+	pBtCoexist->chip_interface = BTC_INTF_UNKNOWN;
+#endif
+
+	EXhalbtcoutsrc_BindBtCoexWithAdapter(padapter);
+
+	pBtCoexist->btc_read_1byte = halbtcoutsrc_Read1Byte;
+	pBtCoexist->btc_write_1byte = halbtcoutsrc_Write1Byte;
+	pBtCoexist->btc_write_1byte_bitmask = halbtcoutsrc_BitMaskWrite1Byte;
+	pBtCoexist->btc_read_2byte = halbtcoutsrc_Read2Byte;
+	pBtCoexist->btc_write_2byte = halbtcoutsrc_Write2Byte;
+	pBtCoexist->btc_read_4byte = halbtcoutsrc_Read4Byte;
+	pBtCoexist->btc_write_4byte = halbtcoutsrc_Write4Byte;
+	pBtCoexist->btc_write_local_reg_1byte = halbtcoutsrc_WriteLocalReg1Byte;
+
+	pBtCoexist->btc_set_bb_reg = halbtcoutsrc_SetBbReg;
+	pBtCoexist->btc_get_bb_reg = halbtcoutsrc_GetBbReg;
+
+	pBtCoexist->btc_set_rf_reg = halbtcoutsrc_SetRfReg;
+	pBtCoexist->btc_get_rf_reg = halbtcoutsrc_GetRfReg;
+
+	pBtCoexist->btc_fill_h2c = halbtcoutsrc_FillH2cCmd;
+	pBtCoexist->btc_disp_dbg_msg = halbtcoutsrc_DisplayDbgMsg;
+
+	pBtCoexist->btc_get = halbtcoutsrc_Get;
+	pBtCoexist->btc_set = halbtcoutsrc_Set;
+	pBtCoexist->btc_get_bt_reg = halbtcoutsrc_GetBtReg;
+	pBtCoexist->btc_set_bt_reg = halbtcoutsrc_SetBtReg;
+	pBtCoexist->btc_set_bt_ant_detection = halbtcoutsrc_SetBtAntDetection;
+	pBtCoexist->btc_coex_h2c_process = halbtcoutsrc_CoexH2cProcess;
+
+	pBtCoexist->cli_buf = &GLBtcDbgBuf[0];
+
+	pBtCoexist->board_info.single_ant_path = 0;
+	
+	GLBtcWiFiInScanState = _FALSE;
+
+	GLBtcWiFiInIQKState = _FALSE;
+
+	GLBtcWiFiInIPS = _FALSE;
+
+	GLBtcWiFiInLPS = _FALSE;
+
+	GLBtcBtCoexAliveRegistered = _FALSE;
+
+	/* BT Control H2C/C2H*/
+	GLBtcBtMpOperSeq = 0;
+	_rtw_mutex_init(&GLBtcBtMpOperLock);
+	timer_setup(&GLBtcBtMpOperTimer, _btmpoper_timer_hdl, 0);
+	_rtw_init_sema(&GLBtcBtMpRptSema, 0);
+	GLBtcBtMpRptSeq = 0;
+	GLBtcBtMpRptStatus = 0;
+	_rtw_memset(GLBtcBtMpRptRsp, 0, C2H_MAX_SIZE);
+	GLBtcBtMpRptRspSize = 0;
+	GLBtcBtMpRptWait = 0;
+	GLBtcBtMpRptWiFiOK = 0;
+	GLBtcBtMpRptBTOK = 0;
+
+	return _TRUE;
+}
+
+void EXhalbtcoutsrc_PowerOnSetting(PBTC_COEXIST pBtCoexist)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	/* Power on setting function is only added in 8723B currently */
+	if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_power_on_setting(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_power_on_setting(pBtCoexist);
+	}
+}
+
+void EXhalbtcoutsrc_PreLoadFirmware(PBTC_COEXIST pBtCoexist)
+{
+	if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+	
+	pBtCoexist->statistics.cntPreLoadFirmware++;
+
+	if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_pre_load_firmware(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_pre_load_firmware(pBtCoexist);
+	}
+}
+
+void EXhalbtcoutsrc_init_hw_config(PBTC_COEXIST pBtCoexist, u8 bWifiOnly)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->statistics.cntInitHwConfig++;
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_init_hw_config(pBtCoexist, bWifiOnly);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_init_hw_config(pBtCoexist, bWifiOnly);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_init_hw_config(pBtCoexist, bWifiOnly);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_init_hw_config(pBtCoexist, bWifiOnly);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_init_hw_config(pBtCoexist, bWifiOnly);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_init_hw_config(pBtCoexist, bWifiOnly);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_init_hw_config(pBtCoexist, bWifiOnly);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_init_hw_config(pBtCoexist, bWifiOnly);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_init_hw_config(pBtCoexist, bWifiOnly);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_init_hw_config(pBtCoexist, bWifiOnly);
+	}
+}
+
+void EXhalbtcoutsrc_init_coex_dm(PBTC_COEXIST pBtCoexist)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->statistics.cntInitCoexDm++;
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_init_coex_dm(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_init_coex_dm(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_init_coex_dm(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_init_coex_dm(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_init_coex_dm(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_init_coex_dm(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_init_coex_dm(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_init_coex_dm(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_init_coex_dm(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_init_coex_dm(pBtCoexist);
+	}
+
+	pBtCoexist->initilized = _TRUE;
+}
+
+void EXhalbtcoutsrc_ips_notify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+	u8	ipsType;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->statistics.cntIpsNotify++;
+	if (pBtCoexist->manual_control)
+		return;
+
+	if (IPS_NONE == type)
+	{
+		ipsType = BTC_IPS_LEAVE;
+		GLBtcWiFiInIPS = _FALSE;
+	}
+	else
+	{
+		ipsType = BTC_IPS_ENTER;
+		GLBtcWiFiInIPS = _TRUE;
+	}
+	
+	// All notify is called in cmd thread, don't need to leave low power again
+//	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_ips_notify(pBtCoexist, ipsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_ips_notify(pBtCoexist, ipsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_ips_notify(pBtCoexist, ipsType);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_ips_notify(pBtCoexist, ipsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_ips_notify(pBtCoexist, ipsType);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_ips_notify(pBtCoexist, ipsType);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_ips_notify(pBtCoexist, ipsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_ips_notify(pBtCoexist, ipsType);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_ips_notify(pBtCoexist, ipsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_ips_notify(pBtCoexist, ipsType);
+	}
+
+//	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_lps_notify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+	u8 lpsType;
+
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->statistics.cntLpsNotify++;
+	if (pBtCoexist->manual_control)
+		return;
+
+	if (PS_MODE_ACTIVE == type)
+	{
+		lpsType = BTC_LPS_DISABLE;
+		GLBtcWiFiInLPS = _FALSE;
+	}
+	else
+	{
+		lpsType = BTC_LPS_ENABLE;
+		GLBtcWiFiInLPS = _TRUE;
+	}
+	
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_lps_notify(pBtCoexist, lpsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_lps_notify(pBtCoexist, lpsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_lps_notify(pBtCoexist, lpsType);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_lps_notify(pBtCoexist, lpsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_lps_notify(pBtCoexist, lpsType);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_lps_notify(pBtCoexist, lpsType);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_lps_notify(pBtCoexist, lpsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_lps_notify(pBtCoexist, lpsType);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_lps_notify(pBtCoexist, lpsType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_lps_notify(pBtCoexist, lpsType);
+	}
+}
+
+void EXhalbtcoutsrc_scan_notify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+	u8	scanType;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+	pBtCoexist->statistics.cntScanNotify++;
+	if (pBtCoexist->manual_control)
+		return;
+
+	if (type)
+	{
+		scanType = BTC_SCAN_START;
+		GLBtcWiFiInScanState = _TRUE;
+	}
+	else
+	{
+		scanType = BTC_SCAN_FINISH;
+		GLBtcWiFiInScanState = _FALSE;
+	}
+
+	// All notify is called in cmd thread, don't need to leave low power again
+//	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_scan_notify(pBtCoexist, scanType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_scan_notify(pBtCoexist, scanType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_scan_notify(pBtCoexist, scanType);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_scan_notify(pBtCoexist, scanType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_scan_notify(pBtCoexist, scanType);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_scan_notify(pBtCoexist, scanType);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_scan_notify(pBtCoexist, scanType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_scan_notify(pBtCoexist, scanType);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_scan_notify(pBtCoexist, scanType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_scan_notify(pBtCoexist, scanType);
+	}
+
+//	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_connect_notify(PBTC_COEXIST pBtCoexist, u8 action)
+{
+	u8	assoType;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+	pBtCoexist->statistics.cntConnectNotify++;
+	if (pBtCoexist->manual_control)
+		return;
+
+	if (action)
+		assoType = BTC_ASSOCIATE_START;
+	else
+		assoType = BTC_ASSOCIATE_FINISH;
+
+	// All notify is called in cmd thread, don't need to leave low power again
+//	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_connect_notify(pBtCoexist, assoType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_connect_notify(pBtCoexist, assoType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_connect_notify(pBtCoexist, assoType);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_connect_notify(pBtCoexist, assoType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_connect_notify(pBtCoexist, assoType);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_connect_notify(pBtCoexist, assoType);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_connect_notify(pBtCoexist, assoType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_connect_notify(pBtCoexist, assoType);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_connect_notify(pBtCoexist, assoType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_connect_notify(pBtCoexist, assoType);
+	}
+
+//	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_media_status_notify(PBTC_COEXIST pBtCoexist, RT_MEDIA_STATUS mediaStatus)
+{
+	u8 mStatus;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->statistics.cntMediaStatusNotify++;
+	if (pBtCoexist->manual_control)
+		return;
+
+	if (RT_MEDIA_CONNECT == mediaStatus)
+		mStatus = BTC_MEDIA_CONNECT;
+	else
+		mStatus = BTC_MEDIA_DISCONNECT;
+
+	// All notify is called in cmd thread, don't need to leave low power again
+//	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_media_status_notify(pBtCoexist, mStatus);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_media_status_notify(pBtCoexist, mStatus);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_media_status_notify(pBtCoexist, mStatus);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_media_status_notify(pBtCoexist, mStatus);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_media_status_notify(pBtCoexist, mStatus);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_media_status_notify(pBtCoexist, mStatus);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_media_status_notify(pBtCoexist, mStatus);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_media_status_notify(pBtCoexist, mStatus);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_media_status_notify(pBtCoexist, mStatus);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_media_status_notify(pBtCoexist, mStatus);
+	}
+
+//	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_specific_packet_notify(PBTC_COEXIST pBtCoexist, u8 pktType)
+{
+	u8	packetType;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+	pBtCoexist->statistics.cntSpecificPacketNotify++;
+	if (pBtCoexist->manual_control)
+		return;
+
+	if (PACKET_DHCP == pktType)
+		packetType = BTC_PACKET_DHCP;
+	else if (PACKET_EAPOL == pktType)
+		packetType = BTC_PACKET_EAPOL;
+	else if (PACKET_ARP == pktType)
+		packetType = BTC_PACKET_ARP;
+	else
+	{
+		packetType = BTC_PACKET_UNKNOWN;
+		return;
+	}
+
+	// All notify is called in cmd thread, don't need to leave low power again
+//	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_specific_packet_notify(pBtCoexist, packetType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_specific_packet_notify(pBtCoexist, packetType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_specific_packet_notify(pBtCoexist, packetType);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_specific_packet_notify(pBtCoexist, packetType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_specific_packet_notify(pBtCoexist, packetType);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_specific_packet_notify(pBtCoexist, packetType);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_specific_packet_notify(pBtCoexist, packetType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_specific_packet_notify(pBtCoexist, packetType);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_specific_packet_notify(pBtCoexist, packetType);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_specific_packet_notify(pBtCoexist, packetType);
+	}
+
+//	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_bt_info_notify(PBTC_COEXIST pBtCoexist, u8 *tmpBuf, u8 length)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->statistics.cntBtInfoNotify++;
+
+	// All notify is called in cmd thread, don't need to leave low power again
+//	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+	}
+
+//	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+VOID
+EXhalbtcoutsrc_RfStatusNotify(
+	IN	PBTC_COEXIST		pBtCoexist,
+	IN	u1Byte 				type
+	)
+{
+	if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+	pBtCoexist->statistics.cntRfStatusNotify++;
+	
+	if(IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+	}
+	else if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_rf_status_notify(pBtCoexist, type);
+	}	
+	else if(IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_rf_status_notify(pBtCoexist, type);
+	}	
+	else if(IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+	}
+	else if(IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+	}
+}
+
+void EXhalbtcoutsrc_StackOperationNotify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+#if 0
+	u8	stackOpType;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+	pBtCoexist->statistics.cntStackOperationNotify++;
+	if (pBtCoexist->manual_control)
+		return;
+
+	if ((HCI_BT_OP_INQUIRY_START == type) ||
+		(HCI_BT_OP_PAGING_START == type) ||
+		(HCI_BT_OP_PAIRING_START == type))
+	{
+		stackOpType = BTC_STACK_OP_INQ_PAGE_PAIR_START;
+	}
+	else if ((HCI_BT_OP_INQUIRY_FINISH == type) ||
+		(HCI_BT_OP_PAGING_SUCCESS == type) ||
+		(HCI_BT_OP_PAGING_UNSUCCESS == type) ||
+		(HCI_BT_OP_PAIRING_FINISH == type) )
+	{
+		stackOpType = BTC_STACK_OP_INQ_PAGE_PAIR_FINISH;
+	}
+	else
+	{
+		stackOpType = BTC_STACK_OP_NONE;
+	}
+
+#endif
+}
+
+void EXhalbtcoutsrc_halt_notify(PBTC_COEXIST pBtCoexist)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_halt_notify(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_halt_notify(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_halt_notify(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_halt_notify(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_halt_notify(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_halt_notify(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_halt_notify(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_halt_notify(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_halt_notify(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_halt_notify(pBtCoexist);
+	}
+
+	pBtCoexist->bBinded = FALSE;
+}
+
+void EXhalbtcoutsrc_SwitchBtTRxMask(PBTC_COEXIST pBtCoexist)
+{
+	if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2) {
+			halbtcoutsrc_SetBtReg(pBtCoexist, 0, 0x3c, 0x01); //BT goto standby while GNT_BT 1-->0
+		} else if (pBtCoexist->board_info.btdm_ant_num == 1) {
+			halbtcoutsrc_SetBtReg(pBtCoexist, 0, 0x3c, 0x15); //BT goto standby while GNT_BT 1-->0
+		}
+	}
+}
+
+void EXhalbtcoutsrc_pnp_notify(PBTC_COEXIST pBtCoexist, u8 pnpState)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	//
+	// currently only 1ant we have to do the notification,
+	// once pnp is notified to sleep state, we have to leave LPS that we can sleep normally.
+	//
+
+	if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_pnp_notify(pBtCoexist, pnpState);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_pnp_notify(pBtCoexist, pnpState);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_pnp_notify(pBtCoexist, pnpState);
+	}
+	else if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_pnp_notify(pBtCoexist, pnpState);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_pnp_notify(pBtCoexist, pnpState);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_pnp_notify(pBtCoexist, pnpState);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_pnp_notify(pBtCoexist, pnpState);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_pnp_notify(pBtCoexist, pnpState);
+	}
+}
+
+void EXhalbtcoutsrc_ScoreBoardStatusNotify(PBTC_COEXIST pBtCoexist, u8 *tmpBuf, u8 length)
+{
+	if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_ScoreBoardStatusNotify(pBtCoexist, tmpBuf, length);
+	}
+}
+
+void EXhalbtcoutsrc_CoexDmSwitch(PBTC_COEXIST pBtCoexist)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+	pBtCoexist->statistics.cntCoexDmSwitch++;
+
+	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+		{
+			pBtCoexist->stop_coex_dm = TRUE;
+			ex_halbtc8723b1ant_coex_dm_reset(pBtCoexist);
+			EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_DETECTED, 2);
+			ex_halbtc8723b2ant_init_hw_config(pBtCoexist, FALSE);
+			ex_halbtc8723b2ant_init_coex_dm(pBtCoexist);
+			pBtCoexist->stop_coex_dm = FALSE;
+		}
+	}
+
+	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_periodical(PBTC_COEXIST pBtCoexist)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+	pBtCoexist->statistics.cntPeriodical++;
+
+	// Periodical should be called in cmd thread,
+	// don't need to leave low power again
+//	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_periodical(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_periodical(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+		{
+			if (!halbtcoutsrc_UnderIps(pBtCoexist))
+			{
+				ex_halbtc8821a1ant_periodical(pBtCoexist);
+			}
+		}
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_periodical(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_periodical(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_periodical(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_periodical(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_periodical(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_periodical(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_periodical(pBtCoexist);
+	}
+
+//	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_dbg_control(PBTC_COEXIST pBtCoexist, u8 opCode, u8 opLen, u8 *pData)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->statistics.cntDbgCtrl++;
+
+	// This function doesn't be called yet,
+	// default no need to leave low power to avoid deadlock
+//	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_dbg_control(pBtCoexist, opCode, opLen, pData);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_dbg_control(pBtCoexist, opCode, opLen, pData);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_dbg_control(pBtCoexist, opCode, opLen, pData);
+	}
+
+//	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+#if 0
+VOID
+EXhalbtcoutsrc_AntennaDetection(
+	IN	PBTC_COEXIST			pBtCoexist,
+	IN	u4Byte					centFreq,
+	IN	u4Byte					offset,
+	IN	u4Byte					span,
+	IN	u4Byte					seconds
+	)
+{
+	if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	/* Need to refine the following power save operations to enable this function in the future */	
+#if 0
+	IPSDisable(pBtCoexist->Adapter, FALSE, 0);
+	LeisurePSLeave(pBtCoexist->Adapter, LPS_DISABLE_BT_COEX);
+#endif
+
+	if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_AntennaDetection(pBtCoexist, centFreq, offset, span, seconds);
+	}
+
+	//IPSReturn(pBtCoexist->Adapter, 0xff);
+}
+#endif
+
+void EXhalbtcoutsrc_StackUpdateProfileInfo(void)
+{
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+	PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+	PADAPTER padapter = (PADAPTER)GLBtCoexist.Adapter;
+	PBT_MGNT pBtMgnt = &padapter->coex_info.BtMgnt;
+	u8 i;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->stack_info.profile_notified = _TRUE;
+
+	pBtCoexist->stack_info.num_of_link =
+		pBtMgnt->ExtConfig.NumberOfACL+pBtMgnt->ExtConfig.NumberOfSCO;
+
+	// reset first
+	pBtCoexist->stack_info.bt_link_exist = _FALSE;
+	pBtCoexist->stack_info.sco_exist = _FALSE;
+	pBtCoexist->stack_info.acl_exist = _FALSE;
+	pBtCoexist->stack_info.a2dp_exist = _FALSE;
+	pBtCoexist->stack_info.hid_exist = _FALSE;
+	pBtCoexist->stack_info.num_of_hid = 0;
+	pBtCoexist->stack_info.pan_exist = _FALSE;
+
+	if (!pBtMgnt->ExtConfig.NumberOfACL)
+		pBtCoexist->stack_info.min_bt_rssi = 0;
+
+	if (pBtCoexist->stack_info.num_of_link)
+	{
+		pBtCoexist->stack_info.bt_link_exist = _TRUE;
+		if (pBtMgnt->ExtConfig.NumberOfSCO)
+			pBtCoexist->stack_info.sco_exist = _TRUE;
+		if (pBtMgnt->ExtConfig.NumberOfACL)
+			pBtCoexist->stack_info.acl_exist = _TRUE;
+	}
+
+	for (i=0; i<pBtMgnt->ExtConfig.NumberOfACL; i++)
+	{
+		if (BT_PROFILE_A2DP == pBtMgnt->ExtConfig.aclLink[i].BTProfile)
+		{
+			pBtCoexist->stack_info.a2dp_exist = _TRUE;
+		}
+		else if (BT_PROFILE_PAN == pBtMgnt->ExtConfig.aclLink[i].BTProfile)
+		{
+			pBtCoexist->stack_info.pan_exist = _TRUE;
+		}
+		else if (BT_PROFILE_HID == pBtMgnt->ExtConfig.aclLink[i].BTProfile)
+		{
+			pBtCoexist->stack_info.hid_exist = _TRUE;
+			pBtCoexist->stack_info.num_of_hid++;
+		}
+		else
+		{
+			pBtCoexist->stack_info.unknown_acl_exist = _TRUE;
+		}
+	}
+#endif //CONFIG_BT_COEXIST_SOCKET_TRX
+}
+
+void EXhalbtcoutsrc_UpdateMinBtRssi(s8 btRssi)
+{
+	PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->stack_info.min_bt_rssi = btRssi;
+}
+
+void EXhalbtcoutsrc_SetHciVersion(u16 hciVersion)
+{
+	PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->stack_info.hci_version = hciVersion;
+}
+
+void EXhalbtcoutsrc_SetBtPatchVersion(u16 btHciVersion, u16 btPatchVersion)
+{
+	PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	pBtCoexist->btInfo.btRealFwVer = btPatchVersion;
+	pBtCoexist->btInfo.btHciVer = btHciVersion;
+}
+
+#if 0
+void EXhalbtcoutsrc_SetBtExist(u8 bBtExist)
+{
+	GLBtCoexist.boardInfo.bBtExist = bBtExist;
+}
+#endif
+void EXhalbtcoutsrc_SetChipType(u8 chipType)
+{
+	switch(chipType)
+	{
+		default:
+		case BT_2WIRE:
+		case BT_ISSC_3WIRE:
+		case BT_ACCEL:
+		case BT_RTL8756:
+			GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_UNDEF;
+			break;
+		case BT_CSR_BC4:
+			GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC4;
+			break;
+		case BT_CSR_BC8:
+			GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC8;
+			break;
+		case BT_RTL8723A:
+			GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_RTL8723A;
+			break;
+		case BT_RTL8821:
+			GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_RTL8821;
+			break;
+		case BT_RTL8723B:
+			GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_RTL8723B;
+			break;
+	}
+}
+
+void EXhalbtcoutsrc_SetAntNum(u8 type, u8 antNum)
+{
+	if (BT_COEX_ANT_TYPE_PG == type)
+	{
+		GLBtCoexist.board_info.pg_ant_num = antNum;
+		GLBtCoexist.board_info.btdm_ant_num = antNum;
+#if 0
+		//The antenna position: Main (default) or Aux for pgAntNum=2 && btdmAntNum =1
+		//The antenna position should be determined by auto-detect mechanism
+		// The following is assumed to main, and those must be modified if y auto-detect mechanism is ready
+		if ((GLBtCoexist.board_info.pg_ant_num == 2) && (GLBtCoexist.board_info.btdm_ant_num == 1))
+			GLBtCoexist.board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
+		else
+			GLBtCoexist.board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
+#endif
+	}
+	else if (BT_COEX_ANT_TYPE_ANTDIV == type)
+	{
+		GLBtCoexist.board_info.btdm_ant_num = antNum;
+		//GLBtCoexist.boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT;	
+	}
+	else if (BT_COEX_ANT_TYPE_DETECTED == type)
+	{
+		GLBtCoexist.board_info.btdm_ant_num = antNum;
+		//GLBtCoexist.boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT;
+	}
+}
+
+//
+// Currently used by 8723b only, S0 or S1
+//
+void EXhalbtcoutsrc_SetSingleAntPath(u8 singleAntPath)
+{
+	GLBtCoexist.board_info.single_ant_path = singleAntPath;
+}
+
+void EXhalbtcoutsrc_DisplayBtCoexInfo(PBTC_COEXIST pBtCoexist)
+{
+	if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter))
+	{
+		if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE)
+			ex_halbtc8821aCsr2ant_display_coex_info(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8821a2ant_display_coex_info(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8821a1ant_display_coex_info(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8723b2ant_display_coex_info(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_display_coex_info(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8703b1ant_display_coex_info(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8192e2ant_display_coex_info(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8192e1ant_display_coex_info(pBtCoexist);
+	}
+	else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_display_coex_info(pBtCoexist);
+		else if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8812a1ant_display_coex_info(pBtCoexist);
+	}
+
+	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_DisplayAntDetection(PBTC_COEXIST pBtCoexist)
+{
+	if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+		return;
+
+	halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+	if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter))
+	{
+		if (pBtCoexist->board_info.btdm_ant_num == 1)
+			ex_halbtc8723b1ant_display_ant_detection(pBtCoexist);
+	}
+	
+	halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_BTOffOnNotify(PBTC_COEXIST pBtCoexist, u8 bBTON)
+{
+#if 0	/*  Jenyu Need commit to windows' SVN */
+	if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+		if (pBtCoexist->board_info.btdm_ant_num == 2)
+			ex_halbtc8812a2ant_bt_off_on_notify(pBtCoexist, (bBTON == _TRUE)?BTC_BT_ON:BTC_BT_OFF);
+	}
+#endif
+}
+
+static void halbt_init_hw_config92C(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	u8 u1Tmp;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	if( (pHalData->bt_coexist.btChipType == BT_CSR_BC4) ||
+		(pHalData->bt_coexist.btChipType == BT_CSR_BC8))
+	{
+		if (pHalData->rf_type == RF_1T1R)
+		{
+			// Config to 1T1R
+			u1Tmp = rtw_read8(padapter, rOFDM0_TRxPathEnable);
+			u1Tmp &= ~BIT(1);
+			rtw_write8(padapter, rOFDM0_TRxPathEnable, u1Tmp);
+			RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xC04 = 0x%x\n", u1Tmp));
+
+			u1Tmp = rtw_read8(padapter, rOFDM1_TRxPathEnable);
+			u1Tmp &= ~BIT(1);
+			rtw_write8(padapter, rOFDM1_TRxPathEnable, u1Tmp);
+			RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xD04 = 0x%x\n", u1Tmp));
+		}
+	}
+}
+
+static void halbt_init_hw_config92D(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	u8 u1Tmp;
+
+	pHalData = GET_HAL_DATA(padapter);
+	if ((pHalData->bt_coexist.btChipType == BT_CSR_BC4) ||
+		(pHalData->bt_coexist.btChipType == BT_CSR_BC8))
+	{
+		if (pHalData->rf_type == RF_1T1R)
+		{
+			// Config to 1T1R
+			u1Tmp = rtw_read8(padapter, rOFDM0_TRxPathEnable);
+			u1Tmp &= ~BIT(1);
+			rtw_write8(padapter, rOFDM0_TRxPathEnable, u1Tmp);
+			RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xC04 = 0x%x\n", u1Tmp));
+
+			u1Tmp = rtw_read8(padapter, rOFDM1_TRxPathEnable);
+			u1Tmp &= ~BIT(1);
+			rtw_write8(padapter, rOFDM1_TRxPathEnable, u1Tmp);
+			RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xD04 = 0x%x\n", u1Tmp));
+		}
+	}
+}
+
+/*
+ * Description:
+ *	Run BT-Coexist mechansim or not
+ *
+ */
+void hal_btcoex_SetBTCoexist(PADAPTER padapter, u8 bBtExist)
+{
+	PHAL_DATA_TYPE	pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	pHalData->bt_coexist.bBtExist = bBtExist;
+
+	//EXhalbtcoutsrc_SetBtExist(bBtExist);
+}
+
+/*
+ * Dewcription:
+ *	Check is co-exist mechanism enabled or not
+ *
+ * Return:
+ *	_TRUE	Enable BT co-exist mechanism
+ *	_FALSE	Disable BT co-exist mechanism
+ */
+u8 hal_btcoex_IsBtExist(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE	pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	return pHalData->bt_coexist.bBtExist;
+}
+
+u8 hal_btcoex_IsBtDisabled(PADAPTER padapter)
+{
+	if (!hal_btcoex_IsBtExist(padapter))
+		return _TRUE;
+
+	if (GLBtCoexist.btInfo.bBtDisabled)
+		return _TRUE;
+	else
+		return _FALSE;
+}
+
+void hal_btcoex_SetChipType(PADAPTER padapter, u8 chipType)
+{
+	PHAL_DATA_TYPE	pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	pHalData->bt_coexist.btChipType = chipType;
+
+	EXhalbtcoutsrc_SetChipType(chipType);
+}
+
+u8 hal_btcoex_GetChipType(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE	pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	return pHalData->bt_coexist.btChipType;
+}
+
+void hal_btcoex_SetPgAntNum(PADAPTER padapter, u8 antNum)
+{
+	PHAL_DATA_TYPE	pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	pHalData->bt_coexist.btTotalAntNum = antNum;
+	EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_PG, antNum);
+}
+
+u8 hal_btcoex_GetPgAntNum(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	return pHalData->bt_coexist.btTotalAntNum;
+}
+
+void hal_btcoex_SetSingleAntPath(PADAPTER padapter, u8 singleAntPath)
+{
+	EXhalbtcoutsrc_SetSingleAntPath(singleAntPath);
+}
+
+u8 hal_btcoex_Initialize(PADAPTER padapter)
+{
+	u8 ret1;
+	u8 ret2;
+
+
+	_rtw_memset(&GLBtCoexist, 0, sizeof(GLBtCoexist));
+	ret1 = EXhalbtcoutsrc_InitlizeVariables((void*)padapter);
+	ret2 = (ret1==_TRUE) ? _TRUE : _FALSE;
+
+	return ret2;
+}
+
+void hal_btcoex_PowerOnSetting(PADAPTER padapter)
+{
+	EXhalbtcoutsrc_PowerOnSetting(&GLBtCoexist);
+}
+
+void hal_btcoex_PreLoadFirmware(PADAPTER padapter)
+{
+	EXhalbtcoutsrc_PreLoadFirmware(&GLBtCoexist);
+}
+
+void hal_btcoex_InitHwConfig(PADAPTER padapter, u8 bWifiOnly)
+{
+	if (!hal_btcoex_IsBtExist(padapter))
+		return;
+
+	EXhalbtcoutsrc_init_hw_config(&GLBtCoexist, bWifiOnly);
+	EXhalbtcoutsrc_init_coex_dm(&GLBtCoexist);
+}
+
+void hal_btcoex_IpsNotify(PADAPTER padapter, u8 type)
+{
+	EXhalbtcoutsrc_ips_notify(&GLBtCoexist, type);
+}
+
+void hal_btcoex_LpsNotify(PADAPTER padapter, u8 type)
+{
+	EXhalbtcoutsrc_lps_notify(&GLBtCoexist, type);
+}
+
+void hal_btcoex_ScanNotify(PADAPTER padapter, u8 type)
+{
+	EXhalbtcoutsrc_scan_notify(&GLBtCoexist, type);
+}
+
+void hal_btcoex_ConnectNotify(PADAPTER padapter, u8 action)
+{
+	EXhalbtcoutsrc_connect_notify(&GLBtCoexist, action);
+}
+
+void hal_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus)
+{
+	EXhalbtcoutsrc_media_status_notify(&GLBtCoexist, mediaStatus);
+}
+
+void hal_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType)
+{
+	EXhalbtcoutsrc_specific_packet_notify(&GLBtCoexist, pktType);
+}
+
+void hal_btcoex_IQKNotify(PADAPTER padapter, u8 state)
+{
+	GLBtcWiFiInIQKState = state;
+}
+
+void hal_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
+{
+	if (GLBtcWiFiInIQKState == _TRUE)
+		return;
+	
+	EXhalbtcoutsrc_bt_info_notify(&GLBtCoexist, tmpBuf, length);
+}
+
+void hal_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
+{
+	u8 extid, status, len, seq;
+
+
+	if (!GLBtcBtMpRptWait)
+		return;
+
+	if ((length < 3) || (!tmpBuf))
+		return;
+
+	extid = tmpBuf[0];
+	/* not response from BT FW then exit*/
+	switch (extid) {
+	case C2H_WIFI_FW_ACTIVE_RSP:
+		GLBtcBtMpRptWiFiOK = 1;
+		return;
+
+	case C2H_TRIG_BY_BT_FW:
+		_cancel_timer_ex(&GLBtcBtMpOperTimer);
+		GLBtcBtMpRptWait = 0;
+		GLBtcBtMpRptBTOK = 1;
+		break;
+
+	default:
+		return;
+	}
+
+	status = tmpBuf[1] & 0xF;
+	len = tmpBuf[1] >> 4;
+	seq = tmpBuf[2] >> 4;
+
+	GLBtcBtMpRptSeq = seq;
+	GLBtcBtMpRptStatus = status;
+	_rtw_memcpy(GLBtcBtMpRptRsp, tmpBuf+3, len);
+	GLBtcBtMpRptRspSize = len;
+	_rtw_up_sema(&GLBtcBtMpRptSema);
+}
+
+void hal_btcoex_SuspendNotify(PADAPTER padapter, u8 state)
+{
+	if (state == 1)
+		state = BTC_WIFI_PNP_SLEEP;
+	else
+		state = BTC_WIFI_PNP_WAKE_UP;
+
+	EXhalbtcoutsrc_pnp_notify(&GLBtCoexist, state);
+}
+
+void hal_btcoex_HaltNotify(PADAPTER padapter)
+{
+	EXhalbtcoutsrc_halt_notify(&GLBtCoexist);
+}
+
+void hal_btcoex_ScoreBoardStatusNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
+{
+	EXhalbtcoutsrc_ScoreBoardStatusNotify(&GLBtCoexist, tmpBuf, length);
+}
+
+void hal_btcoex_SwitchBtTRxMask(PADAPTER padapter)
+{
+	EXhalbtcoutsrc_SwitchBtTRxMask(&GLBtCoexist);
+}
+
+void hal_btcoex_Hanlder(PADAPTER padapter)
+{
+	EXhalbtcoutsrc_periodical(&GLBtCoexist);
+}
+
+s32 hal_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter)
+{
+	return (s32)GLBtCoexist.btInfo.bRejectAggPkt;
+}
+
+s32 hal_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter)
+{
+	return (s32)GLBtCoexist.btInfo.bBtCtrlAggBufSize;
+}
+
+u32 hal_btcoex_GetAMPDUSize(PADAPTER padapter)
+{
+	return (u32)GLBtCoexist.btInfo.aggBufSize;
+}
+
+void hal_btcoex_SetManualControl(PADAPTER padapter, u8 bmanual)
+{
+	GLBtCoexist.manual_control = bmanual;
+}
+
+u8 hal_btcoex_1Ant(PADAPTER padapter)
+{
+	if (hal_btcoex_IsBtExist(padapter) == _FALSE)
+		return _FALSE;
+
+	if (GLBtCoexist.board_info.btdm_ant_num == 1)
+		return _TRUE;
+
+	return _FALSE;
+}
+
+u8 hal_btcoex_IsBtControlLps(PADAPTER padapter)
+{
+	if (hal_btcoex_IsBtExist(padapter) == _FALSE)
+		return _FALSE;
+
+	if (GLBtCoexist.btInfo.bBtDisabled)
+		return _FALSE;
+
+	if (GLBtCoexist.btInfo.bBtCtrlLps)
+		return _TRUE;
+
+	return _FALSE;
+}
+
+u8 hal_btcoex_IsLpsOn(PADAPTER padapter)
+{
+	if (hal_btcoex_IsBtExist(padapter) == _FALSE)
+		return _FALSE;
+
+	if (GLBtCoexist.btInfo.bBtDisabled)
+		return _FALSE;
+
+	if (GLBtCoexist.btInfo.bBtLpsOn)
+		return _TRUE;
+
+	return _FALSE;
+}
+
+u8 hal_btcoex_RpwmVal(PADAPTER padapter)
+{
+	return GLBtCoexist.btInfo.rpwmVal;
+}
+
+u8 hal_btcoex_LpsVal(PADAPTER padapter)
+{
+	return GLBtCoexist.btInfo.lpsVal;
+}
+
+u32 hal_btcoex_GetRaMask(PADAPTER padapter)
+{
+	if (!hal_btcoex_IsBtExist(padapter))
+		return 0;
+
+	if (GLBtCoexist.btInfo.bBtDisabled)
+		return 0;
+
+		/* Modify by YiWei , suggest by Cosa and Jenyu
+		 * Remove the limit antenna number , because 2 antenna case (ex: 8192eu)also want to get BT coex report rate mask.
+		 */
+	/*if (GLBtCoexist.board_info.btdm_ant_num != 1)
+		return 0;*/
+
+	return GLBtCoexist.btInfo.raMask;
+}
+
+void hal_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen)
+{
+	RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW write pwrModeCmd=0x%04x%08x\n",
+		pCmdBuf[0]<<8|pCmdBuf[1],
+		pCmdBuf[2]<<24|pCmdBuf[3]<<16|pCmdBuf[4]<<8|pCmdBuf[5]));
+
+	_rtw_memcpy(GLBtCoexist.pwrModeVal, pCmdBuf, cmdLen);
+}
+
+void hal_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize)
+{
+	PBTCDBGINFO pinfo;
+
+
+	pinfo = &GLBtcDbgInfo;
+	DBG_BT_INFO_INIT(pinfo, pbuf, bufsize);
+	EXhalbtcoutsrc_DisplayBtCoexInfo(&GLBtCoexist);
+	DBG_BT_INFO_INIT(pinfo, NULL, 0);
+}
+
+void hal_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule)
+{
+	u32 i;
+
+
+	if (NULL == pDbgModule)
+		return;
+
+	for (i = 0; i < COMP_MAX; i++)
+		GLBtcDbgType[i] = pDbgModule[i];
+}
+
+u32 hal_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize)
+{
+	s32 count;
+	u8 *pstr;
+	u32 leftSize;
+
+
+	if ((NULL == pStrBuf) || (0 == bufSize))
+		return 0;
+
+	count = 0;
+	pstr = pStrBuf;
+	leftSize = bufSize;
+//	DBG_871X(FUNC_ADPT_FMT ": bufsize=%d\n", FUNC_ADPT_ARG(padapter), bufSize);
+
+	count = rtw_sprintf(pstr, leftSize, "#define DBG\t%d\n", DBG);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+
+	count = rtw_sprintf(pstr, leftSize, "BTCOEX Debug Setting:\n");
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+
+	count = rtw_sprintf(pstr, leftSize,
+		"COMP_COEX: 0x%08X\n\n",
+		GLBtcDbgType[COMP_COEX]);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+
+#if 0
+	count = rtw_sprintf(pstr, leftSize, "INTERFACE Debug Setting Definition:\n");
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[0]=%d for INTF_INIT\n",
+		GLBtcDbgType[BTC_MSG_INTERFACE]&INTF_INIT?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[2]=%d for INTF_NOTIFY\n\n",
+		GLBtcDbgType[BTC_MSG_INTERFACE]&INTF_NOTIFY?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	
+	count = rtw_sprintf(pstr, leftSize, "ALGORITHM Debug Setting Definition:\n");
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[0]=%d for BT_RSSI_STATE\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_BT_RSSI_STATE?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[1]=%d for WIFI_RSSI_STATE\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_WIFI_RSSI_STATE?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[2]=%d for BT_MONITOR\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_BT_MONITOR?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[3]=%d for TRACE\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[4]=%d for TRACE_FW\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_FW?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[5]=%d for TRACE_FW_DETAIL\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_FW_DETAIL?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[6]=%d for TRACE_FW_EXEC\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_FW_EXEC?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[7]=%d for TRACE_SW\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_SW?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[8]=%d for TRACE_SW_DETAIL\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_SW_DETAIL?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+	count = rtw_sprintf(pstr, leftSize, "\tbit[9]=%d for TRACE_SW_EXEC\n",
+		GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_SW_EXEC?1:0);
+	if ((count < 0) || (count >= leftSize))
+		goto exit;
+	pstr += count;
+	leftSize -= count;
+#endif
+
+exit:
+	count = pstr - pStrBuf;
+//	DBG_871X(FUNC_ADPT_FMT ": usedsize=%d\n", FUNC_ADPT_ARG(padapter), count);
+
+	return count;
+}
+
+u8 hal_btcoex_IncreaseScanDeviceNum(PADAPTER padapter)
+{
+	if (!hal_btcoex_IsBtExist(padapter))
+		return _FALSE;
+
+	if (GLBtCoexist.btInfo.bIncreaseScanDevNum)
+		return _TRUE;
+
+	return _FALSE;
+}
+
+u8 hal_btcoex_IsBtLinkExist(PADAPTER padapter)
+{
+	if (GLBtCoexist.bt_link_info.bt_link_exist)
+		return _TRUE;
+
+	return _FALSE;
+}
+
+void hal_btcoex_SetBtPatchVersion(PADAPTER padapter,u16 btHciVer,u16 btPatchVer)
+{
+	EXhalbtcoutsrc_SetBtPatchVersion(btHciVer,btPatchVer);
+}
+
+void hal_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion)
+{
+	EXhalbtcoutsrc_SetHciVersion(hciVersion);
+}
+
+void hal_btcoex_StackUpdateProfileInfo(void)
+{
+	EXhalbtcoutsrc_StackUpdateProfileInfo();
+}
+
+void hal_btcoex_BTOffOnNotify(PADAPTER padapter, u8 bBTON)
+{
+	EXhalbtcoutsrc_BTOffOnNotify(&GLBtCoexist, bBTON);
+}
+
+/*
+ *	Description:
+ *	Setting BT coex antenna isolation type .
+ *	coex mechanisn/ spital stream/ best throughput
+ *	anttype = 0	,	PSTDMA	/	2SS	/	0.5T	,	bad isolation , WiFi/BT ANT Distance<15cm , (<20dB) for 2,3 antenna
+ *	anttype = 1	,	PSTDMA	/	1SS	/	0.5T	,	normal isolaiton , 50cm>WiFi/BT ANT Distance>15cm , (>20dB) for 2 antenna
+ *	anttype = 2	,	TDMA	/	2SS	/	T ,		normal isolaiton , 50cm>WiFi/BT ANT Distance>15cm , (>20dB) for 3 antenna
+ *	anttype = 3	,	no TDMA	/	1SS	/	0.5T	,	good isolation , WiFi/BT ANT Distance >50cm , (>40dB) for 2 antenna
+ *	anttype = 4	,	no TDMA	/	2SS	/	T ,		good isolation , WiFi/BT ANT Distance >50cm , (>40dB) for 3 antenna
+ *	wifi only throughput ~ T
+ *	wifi/BT share one antenna with SPDT
+ */
+void hal_btcoex_SetAntIsolationType(PADAPTER padapter, u8 anttype)
+{
+		PHAL_DATA_TYPE pHalData;
+		PBTC_COEXIST	pBtCoexist = &GLBtCoexist;
+
+		/*DBG_871X("####%s , anttype = %d  , %d\n" , __func__ , anttype , __LINE__); */
+		pHalData = GET_HAL_DATA(padapter);
+
+
+		pHalData->bt_coexist.btAntisolation = anttype;
+
+		switch (pHalData->bt_coexist.btAntisolation) {
+		case 0:
+				pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_0;
+				break;
+		case 1:
+				pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_1;
+				break;
+		case 2:
+				pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_2;
+				break;
+		case 3:
+				pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_3;
+				break;
+		case 4:
+				pBtCoexist->board_info.ant_type = (u1Byte)BTC_ANT_TYPE_4;
+				break;
+		}
+
+}
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+int
+hal_btcoex_ParseAntIsolationConfigFile(
+  PADAPTER		Adapter,
+  char*			buffer
+)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	u32	i = 0 , j = 0;
+	char	*szLine , *ptmp;
+	int rtStatus = _SUCCESS;
+	char param_value_string[10];
+	u8 param_value;
+	u8 anttype = 4;
+	
+	u8 ant_num = 3 , ant_distance = 50 , rfe_type = 1; 
+	
+	typedef struct ant_isolation {
+		char *param_name;  /* antenna isolation config parameter name */ 
+		u8 *value; /* antenna isolation config parameter value */
+	} ANT_ISOLATION;
+
+	ANT_ISOLATION ant_isolation_param[] = {
+												{"ANT_NUMBER" , &ant_num},
+												{"ANT_DISTANCE" , &ant_distance},
+												{"RFE_TYPE" , &rfe_type},												
+												{NULL , 0}
+										};
+
+
+	
+	/* DBG_871X("===>Hal_ParseAntIsolationConfigFile()\n" ); */
+			
+	ptmp = buffer;
+	for (szLine = GetLineFromBuffer(ptmp) ; szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+		/* skip comment */ 
+		if (IsCommentString(szLine))
+			continue;	 
+
+		/* DBG_871X("%s : szLine = %s , strlen(szLine) = %d\n" , __func__ , szLine , strlen(szLine));*/
+		for (j = 0 ; ant_isolation_param[j].param_name != NULL ; j++) {
+			if (strstr(szLine , ant_isolation_param[j].param_name) != NULL) {
+				i = 0;
+				while (i < strlen(szLine)) {
+					if (szLine[i] != '"')
+						++i;
+					else {
+						/* skip only has one " */
+						if (strpbrk(szLine , "\"") == strrchr(szLine , '"')) {
+							DBG_871X("Fail to parse parameters , format error!\n");
+							break;
+						}
+						_rtw_memset((PVOID)param_value_string , 0 , 10);
+						if (!ParseQualifiedString(szLine , &i , param_value_string , '"' , '"')) {
+							DBG_871X("Fail to parse parameters\n");
+							return _FAIL;
+						} else if (!GetU1ByteIntegerFromStringInDecimal(param_value_string , ant_isolation_param[j].value)) 
+							DBG_871X("Fail to GetU1ByteIntegerFromStringInDecimal\n");
+
+						break;
+					}
+				}
+			}
+		}
+	} 
+
+	/* YiWei 20140716 , for BT coex antenna isolation control */
+	/* rfe_type = 0 was SPDT , rfe_type = 1 was coupler */
+	if (ant_num == 3 && ant_distance >= 50) 
+		anttype = 3;
+	else if (ant_num == 2 && ant_distance >= 50 && rfe_type == 1)
+		anttype = 2;
+	else if (ant_num == 3 && ant_distance >= 15 && ant_distance < 50)
+		anttype = 2;
+	else if (ant_num == 2 && ant_distance >= 15 && ant_distance < 50 && rfe_type == 1)
+		anttype = 2;
+	else if ((ant_num == 2 && ant_distance < 15 && rfe_type == 1) || (ant_num == 3 && ant_distance < 15))
+		anttype = 1;
+	else if (ant_num == 2 && rfe_type == 0)
+		anttype = 0;
+	else 
+		anttype = 0;
+
+	hal_btcoex_SetAntIsolationType(Adapter, anttype); 
+						
+	DBG_871X("%s : ant_num = %d\n" , __func__ , ant_num);
+	DBG_871X("%s : ant_distance = %d\n" , __func__ , ant_distance);
+	DBG_871X("%s : rfe_type = %d\n" , __func__ , rfe_type);
+	/* DBG_871X("<===Hal_ParseAntIsolationConfigFile()\n"); */
+	return rtStatus;	
+}
+
+
+int
+hal_btcoex_AntIsolationConfig_ParaFile(
+	IN	PADAPTER	Adapter,
+	IN	char*	 	pFileName
+)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+	int	rlen = 0 , rtStatus = _FAIL;
+
+	_rtw_memset(pHalData->para_file_buf , 0 , MAX_PARA_FILE_BUF_LEN);
+
+
+	rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
+
+	if (rtw_is_file_readable(file__path) == _TRUE)
+	{
+		rlen = rtw_retrieve_from_file(file__path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+		if (rlen > 0)
+		{
+			rtStatus = _SUCCESS;
+		}
+	}
+
+
+	if (rtStatus == _SUCCESS) {
+		/*DBG_871X("%s(): read %s ok\n", __func__ , pFileName);*/
+		rtStatus = hal_btcoex_ParseAntIsolationConfigFile(Adapter , pHalData->para_file_buf);
+	} else {
+		DBG_871X("%s(): No File %s, Load from *** Array!\n" , __func__ , pFileName);
+	}
+
+	return rtStatus;
+}
+#endif // CONFIG_LOAD_PHY_PARA_FROM_FILE
+
+u16 hal_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data)
+{
+	u16 ret = 0;
+
+	halbtcoutsrc_LeaveLowPower(&GLBtCoexist);
+
+	ret = halbtcoutsrc_GetBtReg(&GLBtCoexist, type, addr, data);
+
+	halbtcoutsrc_NormalLowPower(&GLBtCoexist);
+
+	return ret;
+}
+
+u16 hal_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val)
+{
+	u16 ret = 0;
+
+	halbtcoutsrc_LeaveLowPower(&GLBtCoexist);
+
+	ret = halbtcoutsrc_SetBtReg(&GLBtCoexist, type, addr, val);
+
+	halbtcoutsrc_NormalLowPower(&GLBtCoexist);
+
+	return ret;
+}
+#endif // CONFIG_BT_COEXIST
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com.c b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com.c
new file mode 100644
index 000000000..229df0d7a
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com.c
@@ -0,0 +1,8102 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#define _HAL_COM_C_
+
+#include <drv_types.h>
+#include "hal_com_h2c.h"
+
+#include "hal_data.h"
+
+//#define CONFIG_GTK_OL_DBG
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+char	file__path[PATH_LENGTH_MAX];
+#endif
+
+void dump_chip_info(HAL_VERSION	ChipVersion)
+{
+	int cnt = 0;
+	u8 buf[128]={0};
+	
+	if (IS_8188E(ChipVersion))
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8188E_");
+	else if (IS_8188F(ChipVersion))
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8188F_");
+	else if (IS_8812_SERIES(ChipVersion))
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8812_");
+	else if (IS_8192E(ChipVersion))
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8192E_");
+	else if (IS_8821_SERIES(ChipVersion))
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8821_");
+	else if (IS_8723B_SERIES(ChipVersion))
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8723B_");
+	else if (IS_8703B_SERIES(ChipVersion))
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8703B_");
+	else if (IS_8814A_SERIES(ChipVersion))
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8814A_");
+	else
+		cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_UNKNOWN_");
+
+	cnt += sprintf((buf+cnt), "%s_", IS_NORMAL_CHIP(ChipVersion)?"Normal_Chip":"Test_Chip");
+	if(IS_CHIP_VENDOR_TSMC(ChipVersion))
+		cnt += sprintf((buf+cnt), "%s_","TSMC");
+	else if(IS_CHIP_VENDOR_UMC(ChipVersion))	
+		cnt += sprintf((buf+cnt), "%s_","UMC");
+	else if(IS_CHIP_VENDOR_SMIC(ChipVersion))
+		cnt += sprintf((buf+cnt), "%s_","SMIC");		
+	
+	if (IS_A_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "A_CUT_");
+	else if (IS_B_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "B_CUT_");
+	else if (IS_C_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "C_CUT_");
+	else if (IS_D_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "D_CUT_");
+	else if (IS_E_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "E_CUT_");
+	else if (IS_F_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "F_CUT_");
+	else if (IS_I_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "I_CUT_");
+	else if (IS_J_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "J_CUT_");
+	else if (IS_K_CUT(ChipVersion))
+		cnt += sprintf((buf+cnt), "K_CUT_");
+	else
+		cnt += sprintf((buf+cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
+
+	if(IS_1T1R(ChipVersion)) cnt += sprintf((buf+cnt), "1T1R_");
+	else if(IS_1T2R(ChipVersion)) cnt += sprintf((buf+cnt), "1T2R_");
+	else if(IS_2T2R(ChipVersion)) cnt += sprintf((buf+cnt), "2T2R_");
+	else if(IS_3T3R(ChipVersion)) cnt += sprintf((buf+cnt), "3T3R_");
+	else if(IS_3T4R(ChipVersion)) cnt += sprintf((buf+cnt), "3T4R_");
+	else if(IS_4T4R(ChipVersion)) cnt += sprintf((buf+cnt), "4T4R_");
+	else cnt += sprintf((buf+cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
+
+	cnt += sprintf((buf+cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
+
+	DBG_871X("%s", buf);
+}
+void rtw_hal_config_rftype(PADAPTER  padapter)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+	
+	if (IS_1T1R(pHalData->VersionID)) {
+		pHalData->rf_type = RF_1T1R;
+		pHalData->NumTotalRFPath = 1;
+	}	
+	else if (IS_2T2R(pHalData->VersionID)) {
+		pHalData->rf_type = RF_2T2R;
+		pHalData->NumTotalRFPath = 2;
+	}
+	else if (IS_1T2R(pHalData->VersionID)) {
+		pHalData->rf_type = RF_1T2R;
+		pHalData->NumTotalRFPath = 2;
+	}
+	else if(IS_3T3R(pHalData->VersionID)) {
+		pHalData->rf_type = RF_3T3R;
+		pHalData->NumTotalRFPath = 3;
+	}	
+	else if(IS_4T4R(pHalData->VersionID)) {
+		pHalData->rf_type = RF_4T4R;
+		pHalData->NumTotalRFPath = 4;
+	}
+	else {
+		pHalData->rf_type = RF_1T1R;
+		pHalData->NumTotalRFPath = 1;
+	}
+	
+	DBG_871X("%s RF_Type is %d TotalTxPath is %d \n", __FUNCTION__, pHalData->rf_type, pHalData->NumTotalRFPath);
+}
+
+#define	EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
+
+/*
+ * Description:
+ * 	Use hardware(efuse), driver parameter(registry) and default channel plan
+ * 	to decide which one should be used.
+ *
+ * Parameters:
+ *	padapter			pointer of adapter
+ *	hw_channel_plan		channel plan from HW (efuse/eeprom)
+ *						BIT[7] software configure mode; 0:Enable, 1:disable
+ *						BIT[6:0] Channel Plan
+ *	sw_channel_plan		channel plan from SW (registry/module param)
+ *	def_channel_plan	channel plan used when HW/SW both invalid
+ *	AutoLoadFail		efuse autoload fail or not
+ *
+ * Return:
+ *	Final channel plan decision
+ *
+ */
+u8
+hal_com_config_channel_plan(
+	IN	PADAPTER	padapter,
+	IN	u8			hw_channel_plan,
+	IN	u8			sw_channel_plan,
+	IN	u8			def_channel_plan,
+	IN	BOOLEAN		AutoLoadFail
+	)
+{
+	PHAL_DATA_TYPE	pHalData;
+	u8 hwConfig;
+	u8 chnlPlan;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	pHalData->bDisableSWChannelPlan = _FALSE;
+	chnlPlan = def_channel_plan;
+
+	if (0xFF == hw_channel_plan)
+		AutoLoadFail = _TRUE;
+
+	if (_FALSE == AutoLoadFail)
+	{
+		u8 hw_chnlPlan;
+
+		hw_chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
+		if (rtw_is_channel_plan_valid(hw_chnlPlan))
+		{
+#ifndef CONFIG_SW_CHANNEL_PLAN
+			if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
+				pHalData->bDisableSWChannelPlan = _TRUE;
+#endif // !CONFIG_SW_CHANNEL_PLAN
+
+			chnlPlan = hw_chnlPlan;
+		}
+	}
+
+	if ((_FALSE == pHalData->bDisableSWChannelPlan)
+		&& rtw_is_channel_plan_valid(sw_channel_plan))
+	{
+		chnlPlan = sw_channel_plan;
+	}
+
+	return chnlPlan;
+}
+
+BOOLEAN
+HAL_IsLegalChannel(
+	IN	PADAPTER	Adapter,
+	IN	u32			Channel
+	)
+{
+	BOOLEAN bLegalChannel = _TRUE;
+
+	if (Channel > 14) {
+		if(IsSupported5G(Adapter->registrypriv.wireless_mode) == _FALSE) {
+			bLegalChannel = _FALSE;
+			DBG_871X("Channel > 14 but wireless_mode do not support 5G\n");
+		}
+	} else if ((Channel <= 14) && (Channel >=1)){
+		if(IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
+			bLegalChannel = _FALSE;
+			DBG_871X("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
+		}
+	} else {
+		bLegalChannel = _FALSE;
+		DBG_871X("Channel is Invalid !!!\n");
+	}
+
+	return bLegalChannel;
+}	
+
+u8	MRateToHwRate(u8 rate)
+{
+	u8	ret = DESC_RATE1M;
+		
+	switch(rate)
+	{
+		case MGN_1M:		    ret = DESC_RATE1M;	break;
+		case MGN_2M:		    ret = DESC_RATE2M;	break;
+		case MGN_5_5M:		    ret = DESC_RATE5_5M;	break;
+		case MGN_11M:		    ret = DESC_RATE11M;	break;
+		case MGN_6M:		    ret = DESC_RATE6M;	break;
+		case MGN_9M:		    ret = DESC_RATE9M;	break;
+		case MGN_12M:		    ret = DESC_RATE12M;	break;
+		case MGN_18M:		    ret = DESC_RATE18M;	break;
+		case MGN_24M:		    ret = DESC_RATE24M;	break;
+		case MGN_36M:		    ret = DESC_RATE36M;	break;
+		case MGN_48M:		    ret = DESC_RATE48M;	break;
+		case MGN_54M:		    ret = DESC_RATE54M;	break;
+
+		case MGN_MCS0:		    ret = DESC_RATEMCS0;	break;
+		case MGN_MCS1:		    ret = DESC_RATEMCS1;	break;
+		case MGN_MCS2:		    ret = DESC_RATEMCS2;	break;
+		case MGN_MCS3:		    ret = DESC_RATEMCS3;	break;
+		case MGN_MCS4:		    ret = DESC_RATEMCS4;	break;
+		case MGN_MCS5:		    ret = DESC_RATEMCS5;	break;
+		case MGN_MCS6:		    ret = DESC_RATEMCS6;	break;
+		case MGN_MCS7:		    ret = DESC_RATEMCS7;	break;
+		case MGN_MCS8:		    ret = DESC_RATEMCS8;	break;
+		case MGN_MCS9:		    ret = DESC_RATEMCS9;	break;
+		case MGN_MCS10:	        ret = DESC_RATEMCS10;	break;
+		case MGN_MCS11:	        ret = DESC_RATEMCS11;	break;
+		case MGN_MCS12:	        ret = DESC_RATEMCS12;	break;
+		case MGN_MCS13:	        ret = DESC_RATEMCS13;	break;
+		case MGN_MCS14:	        ret = DESC_RATEMCS14;	break;
+		case MGN_MCS15:	        ret = DESC_RATEMCS15;	break;
+		case MGN_MCS16:		    ret = DESC_RATEMCS16;	break;
+		case MGN_MCS17:		    ret = DESC_RATEMCS17;	break;
+		case MGN_MCS18:		    ret = DESC_RATEMCS18;	break;
+		case MGN_MCS19:		    ret = DESC_RATEMCS19;	break;
+		case MGN_MCS20:	        ret = DESC_RATEMCS20;	break;
+		case MGN_MCS21:	        ret = DESC_RATEMCS21;	break;
+		case MGN_MCS22:	        ret = DESC_RATEMCS22;	break;
+		case MGN_MCS23:	        ret = DESC_RATEMCS23;	break;
+		case MGN_MCS24:	        ret = DESC_RATEMCS24;	break;
+		case MGN_MCS25:	        ret = DESC_RATEMCS25;	break;
+		case MGN_MCS26:		    ret = DESC_RATEMCS26;	break;
+		case MGN_MCS27:		    ret = DESC_RATEMCS27;	break;
+		case MGN_MCS28:		    ret = DESC_RATEMCS28;	break;
+		case MGN_MCS29:		    ret = DESC_RATEMCS29;	break;
+		case MGN_MCS30:	        ret = DESC_RATEMCS30;	break;
+		case MGN_MCS31:	        ret = DESC_RATEMCS31;	break;
+
+		case MGN_VHT1SS_MCS0:	ret = DESC_RATEVHTSS1MCS0;	break;
+		case MGN_VHT1SS_MCS1:	ret = DESC_RATEVHTSS1MCS1;	break;
+		case MGN_VHT1SS_MCS2:	ret = DESC_RATEVHTSS1MCS2;	break;
+		case MGN_VHT1SS_MCS3:	ret = DESC_RATEVHTSS1MCS3;	break;
+		case MGN_VHT1SS_MCS4:	ret = DESC_RATEVHTSS1MCS4;	break;
+		case MGN_VHT1SS_MCS5:	ret = DESC_RATEVHTSS1MCS5;	break;
+		case MGN_VHT1SS_MCS6:	ret = DESC_RATEVHTSS1MCS6;	break;
+		case MGN_VHT1SS_MCS7:	ret = DESC_RATEVHTSS1MCS7;	break;
+		case MGN_VHT1SS_MCS8:	ret = DESC_RATEVHTSS1MCS8;	break;
+		case MGN_VHT1SS_MCS9:	ret = DESC_RATEVHTSS1MCS9;	break;	
+		case MGN_VHT2SS_MCS0:	ret = DESC_RATEVHTSS2MCS0;	break;
+		case MGN_VHT2SS_MCS1:	ret = DESC_RATEVHTSS2MCS1;	break;
+		case MGN_VHT2SS_MCS2:	ret = DESC_RATEVHTSS2MCS2;	break;
+		case MGN_VHT2SS_MCS3:	ret = DESC_RATEVHTSS2MCS3;	break;
+		case MGN_VHT2SS_MCS4:	ret = DESC_RATEVHTSS2MCS4;	break;
+		case MGN_VHT2SS_MCS5:	ret = DESC_RATEVHTSS2MCS5;	break;
+		case MGN_VHT2SS_MCS6:	ret = DESC_RATEVHTSS2MCS6;	break;
+		case MGN_VHT2SS_MCS7:	ret = DESC_RATEVHTSS2MCS7;	break;
+		case MGN_VHT2SS_MCS8:	ret = DESC_RATEVHTSS2MCS8;	break;
+		case MGN_VHT2SS_MCS9:	ret = DESC_RATEVHTSS2MCS9;	break;	
+		case MGN_VHT3SS_MCS0:	ret = DESC_RATEVHTSS3MCS0;	break;
+		case MGN_VHT3SS_MCS1:	ret = DESC_RATEVHTSS3MCS1;	break;
+		case MGN_VHT3SS_MCS2:	ret = DESC_RATEVHTSS3MCS2;	break;
+		case MGN_VHT3SS_MCS3:	ret = DESC_RATEVHTSS3MCS3;	break;
+		case MGN_VHT3SS_MCS4:	ret = DESC_RATEVHTSS3MCS4;	break;
+		case MGN_VHT3SS_MCS5:	ret = DESC_RATEVHTSS3MCS5;	break;
+		case MGN_VHT3SS_MCS6:	ret = DESC_RATEVHTSS3MCS6;	break;
+		case MGN_VHT3SS_MCS7:	ret = DESC_RATEVHTSS3MCS7;	break;
+		case MGN_VHT3SS_MCS8:	ret = DESC_RATEVHTSS3MCS8;	break;
+		case MGN_VHT3SS_MCS9:	ret = DESC_RATEVHTSS3MCS9;	break;
+		case MGN_VHT4SS_MCS0:	ret = DESC_RATEVHTSS4MCS0;	break;
+		case MGN_VHT4SS_MCS1:	ret = DESC_RATEVHTSS4MCS1;	break;
+		case MGN_VHT4SS_MCS2:	ret = DESC_RATEVHTSS4MCS2;	break;
+		case MGN_VHT4SS_MCS3:	ret = DESC_RATEVHTSS4MCS3;	break;
+		case MGN_VHT4SS_MCS4:	ret = DESC_RATEVHTSS4MCS4;	break;
+		case MGN_VHT4SS_MCS5:	ret = DESC_RATEVHTSS4MCS5;	break;
+		case MGN_VHT4SS_MCS6:	ret = DESC_RATEVHTSS4MCS6;	break;
+		case MGN_VHT4SS_MCS7:	ret = DESC_RATEVHTSS4MCS7;	break;
+		case MGN_VHT4SS_MCS8:	ret = DESC_RATEVHTSS4MCS8;	break;
+		case MGN_VHT4SS_MCS9:	ret = DESC_RATEVHTSS4MCS9;	break;
+		default:		break;
+	}
+
+	return ret;
+}
+
+u8	HwRateToMRate(u8 rate)
+{
+	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_RATEMCS16:	    ret_rate = MGN_MCS16;	break;
+		case DESC_RATEMCS17:	    ret_rate = MGN_MCS17;	break;
+		case DESC_RATEMCS18:	    ret_rate = MGN_MCS18;	break;
+		case DESC_RATEMCS19:	    ret_rate = MGN_MCS19;	break;
+		case DESC_RATEMCS20:	    ret_rate = MGN_MCS20;	break;
+		case DESC_RATEMCS21:	    ret_rate = MGN_MCS21;	break;
+		case DESC_RATEMCS22:	    ret_rate = MGN_MCS22;	break;
+		case DESC_RATEMCS23:	    ret_rate = MGN_MCS23;	break;
+		case DESC_RATEMCS24:	    ret_rate = MGN_MCS24;	break;
+		case DESC_RATEMCS25:	    ret_rate = MGN_MCS25;	break;
+		case DESC_RATEMCS26:	    ret_rate = MGN_MCS26;	break;
+		case DESC_RATEMCS27:	    ret_rate = MGN_MCS27;	break;
+		case DESC_RATEMCS28:	    ret_rate = MGN_MCS28;	break;
+		case DESC_RATEMCS29:	    ret_rate = MGN_MCS29;	break;
+		case DESC_RATEMCS30:	    ret_rate = MGN_MCS30;	break;
+		case DESC_RATEMCS31:	    ret_rate = MGN_MCS31;	break;
+		case DESC_RATEVHTSS1MCS0:	ret_rate = MGN_VHT1SS_MCS0;		break;
+		case DESC_RATEVHTSS1MCS1:	ret_rate = MGN_VHT1SS_MCS1;		break;
+		case DESC_RATEVHTSS1MCS2:	ret_rate = MGN_VHT1SS_MCS2;		break;
+		case DESC_RATEVHTSS1MCS3:	ret_rate = MGN_VHT1SS_MCS3;		break;
+		case DESC_RATEVHTSS1MCS4:	ret_rate = MGN_VHT1SS_MCS4;		break;
+		case DESC_RATEVHTSS1MCS5:	ret_rate = MGN_VHT1SS_MCS5;		break;
+		case DESC_RATEVHTSS1MCS6:	ret_rate = MGN_VHT1SS_MCS6;		break;
+		case DESC_RATEVHTSS1MCS7:	ret_rate = MGN_VHT1SS_MCS7;		break;
+		case DESC_RATEVHTSS1MCS8:	ret_rate = MGN_VHT1SS_MCS8;		break;
+		case DESC_RATEVHTSS1MCS9:	ret_rate = MGN_VHT1SS_MCS9;		break;
+		case DESC_RATEVHTSS2MCS0:	ret_rate = MGN_VHT2SS_MCS0;		break;
+		case DESC_RATEVHTSS2MCS1:	ret_rate = MGN_VHT2SS_MCS1;		break;
+		case DESC_RATEVHTSS2MCS2:	ret_rate = MGN_VHT2SS_MCS2;		break;
+		case DESC_RATEVHTSS2MCS3:	ret_rate = MGN_VHT2SS_MCS3;		break;
+		case DESC_RATEVHTSS2MCS4:	ret_rate = MGN_VHT2SS_MCS4;		break;
+		case DESC_RATEVHTSS2MCS5:	ret_rate = MGN_VHT2SS_MCS5;		break;
+		case DESC_RATEVHTSS2MCS6:	ret_rate = MGN_VHT2SS_MCS6;		break;
+		case DESC_RATEVHTSS2MCS7:	ret_rate = MGN_VHT2SS_MCS7;		break;
+		case DESC_RATEVHTSS2MCS8:	ret_rate = MGN_VHT2SS_MCS8;		break;
+		case DESC_RATEVHTSS2MCS9:	ret_rate = MGN_VHT2SS_MCS9;		break;				
+		case DESC_RATEVHTSS3MCS0:	ret_rate = MGN_VHT3SS_MCS0;		break;
+		case DESC_RATEVHTSS3MCS1:	ret_rate = MGN_VHT3SS_MCS1;		break;
+		case DESC_RATEVHTSS3MCS2:	ret_rate = MGN_VHT3SS_MCS2;		break;
+		case DESC_RATEVHTSS3MCS3:	ret_rate = MGN_VHT3SS_MCS3;		break;
+		case DESC_RATEVHTSS3MCS4:	ret_rate = MGN_VHT3SS_MCS4;		break;
+		case DESC_RATEVHTSS3MCS5:	ret_rate = MGN_VHT3SS_MCS5;		break;
+		case DESC_RATEVHTSS3MCS6:	ret_rate = MGN_VHT3SS_MCS6;		break;
+		case DESC_RATEVHTSS3MCS7:	ret_rate = MGN_VHT3SS_MCS7;		break;
+		case DESC_RATEVHTSS3MCS8:	ret_rate = MGN_VHT3SS_MCS8;		break;
+		case DESC_RATEVHTSS3MCS9:	ret_rate = MGN_VHT3SS_MCS9;		break;				
+		case DESC_RATEVHTSS4MCS0:	ret_rate = MGN_VHT4SS_MCS0;		break;
+		case DESC_RATEVHTSS4MCS1:	ret_rate = MGN_VHT4SS_MCS1;		break;
+		case DESC_RATEVHTSS4MCS2:	ret_rate = MGN_VHT4SS_MCS2;		break;
+		case DESC_RATEVHTSS4MCS3:	ret_rate = MGN_VHT4SS_MCS3;		break;
+		case DESC_RATEVHTSS4MCS4:	ret_rate = MGN_VHT4SS_MCS4;		break;
+		case DESC_RATEVHTSS4MCS5:	ret_rate = MGN_VHT4SS_MCS5;		break;
+		case DESC_RATEVHTSS4MCS6:	ret_rate = MGN_VHT4SS_MCS6;		break;
+		case DESC_RATEVHTSS4MCS7:	ret_rate = MGN_VHT4SS_MCS7;		break;
+		case DESC_RATEVHTSS4MCS8:	ret_rate = MGN_VHT4SS_MCS8;		break;
+		case DESC_RATEVHTSS4MCS9:	ret_rate = MGN_VHT4SS_MCS9;		break;				
+		
+		default:							
+			DBG_871X("HwRateToMRate(): Non supported Rate [%x]!!!\n",rate );
+			break;
+	}
+
+	return ret_rate;
+}
+
+void	HalSetBrateCfg(
+	IN PADAPTER		Adapter,
+	IN u8			*mBratesOS,
+	OUT u16			*pBrateCfg)
+{
+	u8	i, is_brate, brate;
+
+	for(i=0;i<NDIS_802_11_LENGTH_RATES_EX;i++)
+	{
+		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
+		brate = mBratesOS[i] & 0x7f;
+		
+		if( is_brate )
+		{		
+			switch(brate)
+			{
+				case IEEE80211_CCK_RATE_1MB:	*pBrateCfg |= RATE_1M;	break;
+				case IEEE80211_CCK_RATE_2MB:	*pBrateCfg |= RATE_2M;	break;
+				case IEEE80211_CCK_RATE_5MB:	*pBrateCfg |= RATE_5_5M;break;
+				case IEEE80211_CCK_RATE_11MB:	*pBrateCfg |= RATE_11M;	break;
+				case IEEE80211_OFDM_RATE_6MB:	*pBrateCfg |= RATE_6M;	break;
+				case IEEE80211_OFDM_RATE_9MB:	*pBrateCfg |= RATE_9M;	break;
+				case IEEE80211_OFDM_RATE_12MB:	*pBrateCfg |= RATE_12M;	break;
+				case IEEE80211_OFDM_RATE_18MB:	*pBrateCfg |= RATE_18M;	break;
+				case IEEE80211_OFDM_RATE_24MB:	*pBrateCfg |= RATE_24M;	break;
+				case IEEE80211_OFDM_RATE_36MB:	*pBrateCfg |= RATE_36M;	break;
+				case IEEE80211_OFDM_RATE_48MB:	*pBrateCfg |= RATE_48M;	break;
+				case IEEE80211_OFDM_RATE_54MB:	*pBrateCfg |= RATE_54M;	break;
+			}
+		}
+	}
+}
+
+static VOID
+_OneOutPipeMapping(
+	IN	PADAPTER	pAdapter
+	)
+{
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
+
+	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
+	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI
+	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];//BE
+	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];//BK
+	
+	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
+	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
+	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
+	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD
+}
+
+static VOID
+_TwoOutPipeMapping(
+	IN	PADAPTER	pAdapter,
+	IN	BOOLEAN	 	bWIFICfg
+	)
+{
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
+
+	if(bWIFICfg){ //WMM
+		
+		//	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA 
+		//{  0, 	1, 	0, 	1, 	0, 	0, 	0, 	0, 		0	};
+		//0:ep_0 num, 1:ep_1 num 
+		
+		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];//VO
+		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI
+		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];//BE
+		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];//BK
+		
+		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
+		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
+		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
+		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD
+		
+	}
+	else{//typical setting
+
+		
+		//BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA 
+		//{  1, 	1, 	0, 	0, 	0, 	0, 	0, 	0, 		0	};			
+		//0:ep_0 num, 1:ep_1 num
+		
+		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
+		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI
+		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];//BE
+		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK
+		
+		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
+		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
+		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
+		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD	
+		
+	}
+	
+}
+
+static VOID _ThreeOutPipeMapping(
+	IN	PADAPTER	pAdapter,
+	IN	BOOLEAN	 	bWIFICfg
+	)
+{
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
+
+	if(bWIFICfg){//for WMM
+		
+		//	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA 
+		//{  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};
+		//0:H, 1:N, 2:L 
+		
+		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
+		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI
+		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE
+		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK
+		
+		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
+		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
+		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
+		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD
+		
+	}
+	else{//typical setting
+
+		
+		//	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA 
+		//{  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			
+		//0:H, 1:N, 2:L 
+		
+		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
+		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI
+		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE
+		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];//BK
+		
+		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
+		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
+		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
+		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD	
+	}
+
+}
+static VOID _FourOutPipeMapping(
+	IN	PADAPTER	pAdapter,
+	IN	BOOLEAN	 	bWIFICfg
+	)
+{
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
+
+	if(bWIFICfg){//for WMM
+		
+		//	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA 
+		//{  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};
+		//0:H, 1:N, 2:L ,3:E
+		
+		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
+		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI
+		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE
+		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK
+		
+		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
+		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
+		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];//HIGH
+		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD
+		
+	}
+	else{//typical setting
+
+		
+		//	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA 
+		//{  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			
+		//0:H, 1:N, 2:L 
+		
+		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
+		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI
+		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE
+		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];//BK
+		
+		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
+		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
+		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];//HIGH
+		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD	
+	}
+
+}
+BOOLEAN
+Hal_MappingOutPipe(
+	IN	PADAPTER	pAdapter,
+	IN	u8		NumOutPipe
+	)
+{
+	struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
+
+	BOOLEAN	 bWIFICfg = (pregistrypriv->wifi_spec) ?_TRUE:_FALSE;
+	
+	BOOLEAN result = _TRUE;
+
+	switch(NumOutPipe)
+	{
+		case 2:
+			_TwoOutPipeMapping(pAdapter, bWIFICfg);
+			break;
+		case 3:
+		case 4:
+			_ThreeOutPipeMapping(pAdapter, bWIFICfg);
+			break;			
+		case 1:
+			_OneOutPipeMapping(pAdapter);
+			break;
+		default:
+			result = _FALSE;
+			break;
+	}
+
+	return result;
+	
+}
+
+void hal_init_macaddr(_adapter *adapter)
+{
+	rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, adapter_mac_addr(adapter));
+#ifdef  CONFIG_CONCURRENT_MODE
+	if (adapter->pbuddy_adapter)
+		rtw_hal_set_hwreg(adapter->pbuddy_adapter, HW_VAR_MAC_ADDR, adapter_mac_addr(adapter->pbuddy_adapter));
+#endif
+}
+
+void rtw_init_hal_com_default_value(PADAPTER Adapter)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+
+	pHalData->AntDetection = 1;
+}
+
+/* 
+* C2H event format:
+* Field	 TRIGGER		CONTENT	   CMD_SEQ 	CMD_LEN		 CMD_ID
+* BITS	 [127:120]	[119:16]      [15:8]		  [7:4]	 	   [3:0]
+*/
+
+void c2h_evt_clear(_adapter *adapter)
+{
+	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
+}
+
+s32 c2h_evt_read(_adapter *adapter, u8 *buf)
+{
+	s32 ret = _FAIL;
+	struct c2h_evt_hdr *c2h_evt;
+	int i;
+	u8 trigger;
+
+	if (buf == NULL)
+		goto exit;
+
+#if defined (CONFIG_RTL8188E)
+
+	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
+
+	if (trigger == C2H_EVT_HOST_CLOSE) {
+		goto exit; /* Not ready */
+	} else if (trigger != C2H_EVT_FW_CLOSE) {
+		goto clear_evt; /* Not a valid value */
+	}
+
+	c2h_evt = (struct c2h_evt_hdr *)buf;
+
+	_rtw_memset(c2h_evt, 0, 16);
+
+	*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
+	*(buf+1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);	
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): ",
+		&c2h_evt , sizeof(c2h_evt));
+
+	if (0) {
+		DBG_871X("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__
+			, c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger);
+	}
+
+	/* Read the content */
+	for (i = 0; i < c2h_evt->plen; i++)
+		c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): Command Content:\n",
+		c2h_evt->payload, c2h_evt->plen);
+
+	ret = _SUCCESS;
+
+clear_evt:
+	/* 
+	* Clear event to notify FW we have read the command.
+	* If this field isn't clear, the FW won't update the next command message.
+	*/
+	c2h_evt_clear(adapter);
+#endif
+exit:
+	return ret;
+}
+
+/* 
+* C2H event format:
+* Field    TRIGGER    CMD_LEN    CONTENT    CMD_SEQ    CMD_ID
+* BITS    [127:120]   [119:112]    [111:16]	     [15:8]         [7:0]
+*/
+s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
+{
+	s32 ret = _FAIL;
+	struct c2h_evt_hdr_88xx *c2h_evt;
+	int i;
+	u8 trigger;
+
+	if (buf == NULL)
+		goto exit;
+
+#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B)
+
+	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
+
+	if (trigger == C2H_EVT_HOST_CLOSE) {
+		goto exit; /* Not ready */
+	} else if (trigger != C2H_EVT_FW_CLOSE) {
+		goto clear_evt; /* Not a valid value */
+	}
+
+	c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
+
+	_rtw_memset(c2h_evt, 0, 16);
+
+	c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
+	c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX);
+	c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): ",
+		&c2h_evt , sizeof(c2h_evt));
+
+	if (0) {
+		DBG_871X("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__
+			, c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger);
+	}
+
+	/* Read the content */
+	for (i = 0; i < c2h_evt->plen; i++)
+		c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): Command Content:\n",
+		c2h_evt->payload, c2h_evt->plen);
+
+	ret = _SUCCESS;
+
+clear_evt:
+	/* 
+	* Clear event to notify FW we have read the command.
+	* If this field isn't clear, the FW won't update the next command message.
+	*/
+	c2h_evt_clear(adapter);
+#endif
+exit:
+	return ret;
+}
+
+#define	GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
+#define	GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
+#define	GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
+#define	GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data)			LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
+#define	GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
+#define	GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 4)
+#define	GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
+#define	GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
+#define	GET_C2H_MAC_HIDDEN_RPT_BW(_data)				LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
+#define	GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
+#define	GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
+#define	GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
+
+#ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
+#define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
+#endif
+
+int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
+{
+	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
+	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+	int ret = _FAIL;
+
+	u32 uuid;
+	u8 uuid_x;
+	u8 uuid_y;
+	u8 uuid_z;
+	u16 uuid_crc;
+
+	u8 hci_type;
+	u8 package_type;
+	u8 wl_func;
+	u8 hw_stype;
+	u8 bw;
+	u8 ant_num;
+	u8 protocol;
+	u8 nic;
+
+	int i;
+
+	if (len < MAC_HIDDEN_RPT_LEN) {
+		DBG_871X_LEVEL(_drv_warning_, "%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
+		goto exit;
+	}
+
+	uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
+	uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
+	uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
+	uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
+
+	hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
+	package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
+
+	wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
+	hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
+
+	bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
+	ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
+
+	protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
+	nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
+
+	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
+		for (i = 0; i < len; i++)
+			DBG_871X("%s: 0x%02X\n", __func__, *(data + i));
+
+		DBG_871X("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
+		DBG_871X("hci_type:0x%x\n", hci_type);
+		DBG_871X("package_type:0x%x\n", package_type);
+		DBG_871X("wl_func:0x%x\n", wl_func);
+		DBG_871X("hw_stype:0x%x\n", hw_stype);
+		DBG_871X("bw:0x%x\n", bw);
+		DBG_871X("ant_num:0x%x\n", ant_num);
+		DBG_871X("protocol:0x%x\n", protocol);
+		DBG_871X("nic:0x%x\n", nic);
+	}
+
+	hal_data->PackageType = package_type;
+	hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
+	hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
+	hal_spec->nss_num = rtw_min(hal_spec->nss_num, ant_num);
+	hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
+
+	ret = _SUCCESS;
+
+exit:
+	return ret;
+}
+
+int hal_read_mac_hidden_rpt(_adapter *adapter)
+{
+	int ret = _FAIL;
+	int ret_fwdl;
+	u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN] = {0};
+	u32 start = rtw_get_current_time();
+	u32 cnt = 0;
+	u32 timeout_ms = 800;
+	u32 min_cnt = 10;
+	u8 id = C2H_MAC_HIDDEN_RPT + 1;
+	int i;
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
+	u8 hci_type = rtw_get_intf_type(adapter);
+
+	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
+		&& !rtw_is_hw_init_completed(adapter))
+		rtw_hal_power_on(adapter);
+#endif
+
+	/* clear data ready */
+	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, id);
+
+	/* download FW */
+	ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
+	if (ret_fwdl != _SUCCESS)
+		goto mac_hidden_rpt_hdl;
+
+	/* polling for data ready */
+	start = rtw_get_current_time();
+	do {
+		cnt++;
+		id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
+		if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
+			break;
+		rtw_msleep_os(10);
+	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
+
+	if (id == C2H_MAC_HIDDEN_RPT) {
+		/* read data */
+		for (i = 0; i < MAC_HIDDEN_RPT_LEN; i++)
+			mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
+	}
+
+mac_hidden_rpt_hdl:
+	c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
+
+	if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
+		ret = _SUCCESS;
+
+exit:
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
+	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
+		&& !rtw_is_hw_init_completed(adapter))
+		rtw_hal_power_off(adapter);
+#endif
+
+	DBG_871X("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
+		, (ret == _SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
+
+	return ret;
+}
+
+u8  rtw_hal_networktype_to_raid(_adapter *adapter, struct sta_info *psta)
+{
+	if(IS_NEW_GENERATION_IC(adapter)){
+		return networktype_to_raid_ex(adapter,psta);
+	}
+	else{
+		return networktype_to_raid(adapter,psta);
+	}
+
+}
+u8 rtw_get_mgntframe_raid(_adapter *adapter,unsigned char network_type)
+{	
+
+	u8 raid;
+	if(IS_NEW_GENERATION_IC(adapter)){
+		
+		raid = (network_type & WIRELESS_11B)	?RATEID_IDX_B
+											:RATEID_IDX_G;		
+	}
+	else{
+		raid = (network_type & WIRELESS_11B)	?RATR_INX_WIRELESS_B
+											:RATR_INX_WIRELESS_G;		
+	}	
+	return raid;
+}
+
+void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
+{
+	u8	i, rf_type, limit;
+	u64	tx_ra_bitmap;
+
+	if(psta == NULL)
+	{
+		return;
+	}
+
+	tx_ra_bitmap = 0;
+
+	//b/g mode ra_bitmap  
+	for (i=0; i<sizeof(psta->bssrateset); i++)
+	{
+		if (psta->bssrateset[i])
+			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
+	}
+
+#ifdef CONFIG_80211N_HT
+#ifdef CONFIG_80211AC_VHT
+	//AC mode ra_bitmap
+	if(psta->vhtpriv.vht_option) 
+	{
+		tx_ra_bitmap |= (rtw_vht_rate_to_bitmap(psta->vhtpriv.vht_mcs_map) << 12);
+	}
+	else
+#endif //CONFIG_80211AC_VHT
+	{
+		//n mode ra_bitmap
+		if(psta->htpriv.ht_option)
+		{
+			rf_type = RF_1T1R;
+			rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+			if(rf_type == RF_2T2R)
+				limit=16;// 2R
+			else if(rf_type == RF_3T3R)
+				limit=24;// 3R
+			else
+				limit=8;//  1R
+
+
+			/* Handling SMPS mode for AP MODE only*/
+			if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
+				/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
+				if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
+					/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
+					limit = 8;/*  1R*/
+				}
+			}
+
+			for (i=0; i<limit; i++) {
+				if (psta->htpriv.ht_cap.supp_mcs_set[i/8] & BIT(i%8))
+					tx_ra_bitmap |= BIT(i+12);
+			}
+		}
+	}
+#endif //CONFIG_80211N_HT
+	DBG_871X("supp_mcs_set = %02x, %02x, %02x, rf_type=%d, tx_ra_bitmap=%016llx\n"
+	, psta->htpriv.ht_cap.supp_mcs_set[0], psta->htpriv.ht_cap.supp_mcs_set[1], psta->htpriv.ht_cap.supp_mcs_set[2], rf_type, tx_ra_bitmap);
+	psta->ra_mask = tx_ra_bitmap;
+	psta->init_rate = get_highest_rate_idx(tx_ra_bitmap)&0x3f;
+}
+
+#ifndef SEC_CAM_ACCESS_TIMEOUT_MS
+	#define SEC_CAM_ACCESS_TIMEOUT_MS 200
+#endif
+
+#ifndef DBG_SEC_CAM_ACCESS
+	#define DBG_SEC_CAM_ACCESS 0
+#endif
+
+u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
+{
+	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
+	u32 rdata;
+	u32 cnt = 0;
+	u32 start = 0, end = 0;
+	u8 timeout = 0;
+	u8 sr = 0;
+
+	_enter_critical_mutex(mutex, NULL);
+
+	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
+
+	start = rtw_get_current_time();
+	while (1) {
+		if (rtw_is_surprise_removed(adapter)) {
+			sr = 1;
+			break;
+		}
+
+		cnt++;
+		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
+			break;
+
+		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
+			timeout = 1;
+			break;
+		}
+	}
+	end = rtw_get_current_time();
+
+	rdata = rtw_read32(adapter, REG_CAMREAD);
+
+	_exit_critical_mutex(mutex, NULL);
+
+	if (DBG_SEC_CAM_ACCESS || timeout) {
+		DBG_871X(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
+			, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
+	}
+
+	return rdata;
+}
+
+void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
+{
+	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
+	u32 cnt = 0;
+	u32 start = 0, end = 0;
+	u8 timeout = 0;
+	u8 sr = 0;
+
+	_enter_critical_mutex(mutex, NULL);
+
+	rtw_write32(adapter, REG_CAMWRITE, wdata);
+	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
+
+	start = rtw_get_current_time();
+	while (1) {
+		if (rtw_is_surprise_removed(adapter)) {
+			sr = 1;
+			break;
+		}
+
+		cnt++;
+		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
+			break;
+
+		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
+			timeout = 1;
+			break;
+		}
+	}
+	end = rtw_get_current_time();
+
+	_exit_critical_mutex(mutex, NULL);
+
+	if (DBG_SEC_CAM_ACCESS || timeout) {
+		DBG_871X(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
+			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
+	}
+}
+
+void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
+{
+	unsigned int val, addr;
+	u8 i;
+	u32 rdata;
+	u8 begin = 0;
+	u8 end = 5; /* TODO: consider other key length accordingly */
+
+	if (!ctrl && !mac && !key) {
+		rtw_warn_on(1);
+		goto exit;
+	}
+
+	/* TODO: check id range */
+
+	if (!ctrl && !mac)
+		begin = 2; /* read from key */
+
+	if (!key && !mac)
+		end = 0; /* read to ctrl */
+	else if (!key)
+		end = 2; /* read to mac */
+
+	for (i = begin; i <= end; i++) {
+		rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
+
+		switch (i) {
+		case 0:
+			if (ctrl)
+				_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
+			if (mac)
+				_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
+			break;
+		case 1:
+			if (mac)
+				_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
+			break;
+		default:
+			if (key)
+				_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
+			break;
+		}
+	}
+
+exit:
+	return;
+}
+
+
+void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
+{
+	unsigned int i;
+	int j;
+	u8 addr;
+	u32 wdata;
+
+	/* TODO: consider other key length accordingly */
+#if 0
+	switch ((ctrl & 0x1c) >> 2) {
+	case _WEP40_:
+	case _TKIP_
+	case _AES_
+	case _WEP104_
+
+	}
+#else
+	j = 5;
+#endif
+
+	for (; j >= 0; j--) {
+		switch (j) {
+		case 0:
+			wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
+			break;
+		case 1:
+			wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
+			break;
+		default:
+			i = (j - 2) << 2;
+			wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
+			break;
+		}
+
+		addr = (id << 3) + j;
+
+		rtw_sec_write_cam(adapter, addr, wdata);
+	}
+}
+
+bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
+{
+	bool res;
+	u16 ctrl;
+
+	rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
+
+	res = (ctrl & BIT6) ? _TRUE : _FALSE;
+	return res;
+}
+
+void hw_var_port_switch(_adapter *adapter)
+{
+#ifdef CONFIG_CONCURRENT_MODE
+#ifdef CONFIG_RUNTIME_PORT_SWITCH
+/*
+0x102: MSR
+0x550: REG_BCN_CTRL
+0x551: REG_BCN_CTRL_1
+0x55A: REG_ATIMWND
+0x560: REG_TSFTR
+0x568: REG_TSFTR1
+0x570: REG_ATIMWND_1
+0x610: REG_MACID
+0x618: REG_BSSID
+0x700: REG_MACID1
+0x708: REG_BSSID1
+*/
+
+	int i;
+	u8 msr;
+	u8 bcn_ctrl;
+	u8 bcn_ctrl_1;
+	u8 atimwnd[2];
+	u8 atimwnd_1[2];
+	u8 tsftr[8];
+	u8 tsftr_1[8];
+	u8 macid[6];
+	u8 bssid[6];
+	u8 macid_1[6];
+	u8 bssid_1[6];
+
+	u8 iface_type;
+
+	msr = rtw_read8(adapter, MSR);
+	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
+	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
+
+	for (i=0; i<2; i++)
+		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND+i);
+	for (i=0; i<2; i++)
+		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1+i);
+
+	for (i=0; i<8; i++)
+		tsftr[i] = rtw_read8(adapter, REG_TSFTR+i);
+	for (i=0; i<8; i++)
+		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1+i);
+
+	for (i=0; i<6; i++)
+		macid[i] = rtw_read8(adapter, REG_MACID+i);
+
+	for (i=0; i<6; i++)
+		bssid[i] = rtw_read8(adapter, REG_BSSID+i);
+
+	for (i=0; i<6; i++)
+		macid_1[i] = rtw_read8(adapter, REG_MACID1+i);
+
+	for (i=0; i<6; i++)
+		bssid_1[i] = rtw_read8(adapter, REG_BSSID1+i);
+
+#ifdef DBG_RUNTIME_PORT_SWITCH
+	DBG_871X(FUNC_ADPT_FMT" before switch\n"
+		"msr:0x%02x\n"
+		"bcn_ctrl:0x%02x\n"
+		"bcn_ctrl_1:0x%02x\n"
+		"atimwnd:0x%04x\n"
+		"atimwnd_1:0x%04x\n"
+		"tsftr:%llu\n"
+		"tsftr1:%llu\n"
+		"macid:"MAC_FMT"\n"
+		"bssid:"MAC_FMT"\n"
+		"macid_1:"MAC_FMT"\n"
+		"bssid_1:"MAC_FMT"\n"
+		, FUNC_ADPT_ARG(adapter)
+		, msr
+		, bcn_ctrl
+		, bcn_ctrl_1
+		, *((u16*)atimwnd)
+		, *((u16*)atimwnd_1)
+		, *((u64*)tsftr)
+		, *((u64*)tsftr_1)
+		, MAC_ARG(macid)
+		, MAC_ARG(bssid)
+		, MAC_ARG(macid_1)
+		, MAC_ARG(bssid_1)
+	);
+#endif /* DBG_RUNTIME_PORT_SWITCH */
+
+	/* disable bcn function, disable update TSF  */
+	rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
+	rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
+
+	/* switch msr */
+	msr = (msr&0xf0) |((msr&0x03) << 2) | ((msr&0x0c) >> 2);
+	rtw_write8(adapter, MSR, msr);
+
+	/* write port0 */
+	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
+	for (i=0; i<2; i++)
+		rtw_write8(adapter, REG_ATIMWND+i, atimwnd_1[i]);
+	for (i=0; i<8; i++)
+		rtw_write8(adapter, REG_TSFTR+i, tsftr_1[i]);
+	for (i=0; i<6; i++)
+		rtw_write8(adapter, REG_MACID+i, macid_1[i]);
+	for (i=0; i<6; i++)
+		rtw_write8(adapter, REG_BSSID+i, bssid_1[i]);
+
+	/* write port1 */
+	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
+	for (i=0; i<2; i++)
+		rtw_write8(adapter, REG_ATIMWND_1+1, atimwnd[i]);
+	for (i=0; i<8; i++)
+		rtw_write8(adapter, REG_TSFTR1+i, tsftr[i]);
+	for (i=0; i<6; i++)
+		rtw_write8(adapter, REG_MACID1+i, macid[i]);
+	for (i=0; i<6; i++)
+		rtw_write8(adapter, REG_BSSID1+i, bssid[i]);
+
+	/* write bcn ctl */
+#ifdef CONFIG_BT_COEXIST
+#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B)
+	// always enable port0 beacon function for PSTDMA
+	bcn_ctrl_1 |= EN_BCN_FUNCTION;
+	// always disable port1 beacon function for PSTDMA
+	bcn_ctrl &= ~EN_BCN_FUNCTION;
+#endif
+#endif
+	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
+	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
+
+	if (adapter->iface_type == IFACE_PORT0) {
+		adapter->iface_type = IFACE_PORT1;
+		adapter->pbuddy_adapter->iface_type = IFACE_PORT0;
+		DBG_871X_LEVEL(_drv_always_, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
+			ADPT_ARG(adapter->pbuddy_adapter), ADPT_ARG(adapter));
+	} else {
+		adapter->iface_type = IFACE_PORT0;
+		adapter->pbuddy_adapter->iface_type = IFACE_PORT1;
+		DBG_871X_LEVEL(_drv_always_, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
+			ADPT_ARG(adapter), ADPT_ARG(adapter->pbuddy_adapter));
+	}
+
+#ifdef DBG_RUNTIME_PORT_SWITCH
+	msr = rtw_read8(adapter, MSR);
+	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
+	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
+
+	for (i=0; i<2; i++)
+		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND+i);
+	for (i=0; i<2; i++)
+		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1+i);
+
+	for (i=0; i<8; i++)
+		tsftr[i] = rtw_read8(adapter, REG_TSFTR+i);
+	for (i=0; i<8; i++)
+		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1+i);
+
+	for (i=0; i<6; i++)
+		macid[i] = rtw_read8(adapter, REG_MACID+i);
+
+	for (i=0; i<6; i++)
+		bssid[i] = rtw_read8(adapter, REG_BSSID+i);
+
+	for (i=0; i<6; i++)
+		macid_1[i] = rtw_read8(adapter, REG_MACID1+i);
+
+	for (i=0; i<6; i++)
+		bssid_1[i] = rtw_read8(adapter, REG_BSSID1+i);
+
+	DBG_871X(FUNC_ADPT_FMT" after switch\n"
+		"msr:0x%02x\n"
+		"bcn_ctrl:0x%02x\n"
+		"bcn_ctrl_1:0x%02x\n"
+		"atimwnd:%u\n"
+		"atimwnd_1:%u\n"
+		"tsftr:%llu\n"
+		"tsftr1:%llu\n"
+		"macid:"MAC_FMT"\n"
+		"bssid:"MAC_FMT"\n"
+		"macid_1:"MAC_FMT"\n"
+		"bssid_1:"MAC_FMT"\n"
+		, FUNC_ADPT_ARG(adapter)
+		, msr
+		, bcn_ctrl
+		, bcn_ctrl_1
+		, *((u16*)atimwnd)
+		, *((u16*)atimwnd_1)
+		, *((u64*)tsftr)
+		, *((u64*)tsftr_1)
+		, MAC_ARG(macid)
+		, MAC_ARG(bssid)
+		, MAC_ARG(macid_1)
+		, MAC_ARG(bssid_1)
+	);
+#endif /* DBG_RUNTIME_PORT_SWITCH */
+
+#endif /* CONFIG_RUNTIME_PORT_SWITCH */
+#endif /* CONFIG_CONCURRENT_MODE */
+}
+
+const char * const _h2c_msr_role_str[] = {
+	"RSVD",
+	"STA",
+	"AP",
+	"GC",
+	"GO",
+	"TDLS",
+	"INVALID",
+};
+
+/*
+* rtw_hal_set_FwMediaStatusRpt_cmd -
+*
+* @adapter:
+* @opmode:  0:disconnect, 1:connect
+* @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
+* @miracast_sink: 0:source. 1:sink
+* @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
+* @macid:
+* @macid_ind:  0:update Media Status to macid.  1:update Media Status from macid to macid_end
+* @macid_end:
+*/
+s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)
+{
+	struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
+	u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
+	int i;
+	s32 ret;
+
+	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
+	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
+	SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
+	SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
+	SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
+	SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
+	SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
+
+	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
+	if (ret != _SUCCESS)
+		goto exit;
+
+#if defined(CONFIG_RTL8188E)
+	if (rtw_get_chip_type(adapter) == RTL8188E) {
+		HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+		/* 8188E FW doesn't set macid no link, driver does it by self */
+		if (opmode)
+			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
+		else
+			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
+
+		/* for 8188E RA */
+		#if (RATE_ADAPTIVE_SUPPORT == 1)
+		if (hal_data->fw_ractrl == _FALSE) {
+			u8 max_macid;
+
+			max_macid = rtw_search_max_mac_id(adapter);
+			rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
+		}
+		#endif
+	}
+#endif
+
+#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
+	/* TODO: this should move to IOT issue area */
+	if (rtw_get_chip_type(adapter) == RTL8812
+		|| rtw_get_chip_type(adapter) == RTL8821
+	) {
+		if (MLME_IS_STA(adapter))
+			Hal_PatchwithJaguar_8812(adapter, opmode);
+	}
+#endif
+
+	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
+	if (macid_ind == 0)
+		macid_end = macid;
+
+	for (i = macid; macid <= macid_end; macid++)
+		rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
+
+exit:
+	return ret;
+}
+
+inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
+{
+	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
+}
+
+inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
+{
+	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
+}
+
+void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+	struct	hal_ops *pHalFunc = &padapter->HalFunc;
+	u8	u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0};
+	u8	ret = 0;
+
+	DBG_871X("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
+		rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
+		rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
+		rsvdpageloc->LocBTQosNull);
+
+	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
+	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
+	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
+	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
+	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
+
+	ret = rtw_hal_fill_h2c_cmd(padapter,
+				H2C_RSVD_PAGE,
+				H2C_RSVDPAGE_LOC_LEN,
+				u1H2CRsvdPageParm);
+
+}
+
+#ifdef CONFIG_GPIO_WAKEUP
+/*
+ * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
+ * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
+ * and implement HAL function.
+ */
+static void rtw_hal_switch_gpio_wl_ctrl(_adapter* padapter, u8 index, u8 enable)
+{
+	if (index !=13 && index != 14) return;
+
+	rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
+}
+
+void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
+{
+	if ( index <= 7 ) {
+		/* config GPIO mode */
+		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
+				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index) );
+
+		/* config GPIO Sel */
+		/* 0: input */
+		/* 1: output */
+		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
+				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
+
+		/* set output value */
+		if ( outputval ) {
+			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
+					rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
+		} else {
+			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
+					rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
+		}
+	} else if (index <= 15){
+		/* 88C Series: */
+		/* index: 11~8 transform to 3~0 */
+		/* 8723 Series: */
+		/* index: 12~8 transform to 4~0 */
+
+		index -= 8;
+
+		/* config GPIO mode */
+		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
+				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index) );
+
+		/* config GPIO Sel */
+		/* 0: input */
+		/* 1: output */
+		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
+				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
+
+		/* set output value */
+		if ( outputval ) {
+			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
+					rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
+		} else {
+			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
+					rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
+		}
+	} else {
+		DBG_871X("%s: invalid GPIO%d=%d\n",
+				__FUNCTION__, index, outputval);
+	}
+}
+#endif
+
+void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+	struct	hal_ops *pHalFunc = &padapter->HalFunc;
+	struct	pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
+	u8	res = 0, count = 0, ret = 0;
+#ifdef CONFIG_WOWLAN	
+	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
+
+	DBG_871X("AOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
+			rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
+			rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
+			rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
+			rsvdpageloc->LocNetList);
+
+	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
+		//SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv);
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
+#ifdef CONFIG_GTK_OL
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
+#endif // CONFIG_GTK_OL
+		ret = rtw_hal_fill_h2c_cmd(padapter,
+					H2C_AOAC_RSVD_PAGE,
+					H2C_AOAC_RSVDPAGE_LOC_LEN,
+					u1H2CAoacRsvdPageParm);
+	}
+#ifdef CONFIG_PNO_SUPPORT
+	else
+	{
+
+		if(!pwrpriv->pno_in_resume) {
+			DBG_871X("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
+			_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
+					sizeof(u1H2CAoacRsvdPageParm));
+			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
+					rsvdpageloc->LocPNOInfo);
+			ret = rtw_hal_fill_h2c_cmd(padapter,
+						H2C_AOAC_RSVDPAGE3,
+						H2C_AOAC_RSVDPAGE_LOC_LEN,
+						u1H2CAoacRsvdPageParm);
+		}
+	}
+#endif //CONFIG_PNO_SUPPORT
+#endif // CONFIG_WOWLAN
+}
+
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+static void rtw_hal_force_enable_rxdma(_adapter *adapter)
+{
+	DBG_871X("%s: Set 0x690=0x00\n", __func__);
+	rtw_write8(adapter, REG_WOW_CTRL,
+			(rtw_read8(adapter, REG_WOW_CTRL)&0xf0));
+	DBG_871X_LEVEL(_drv_always_, "%s: Release RXDMA\n", __func__);
+	rtw_write32(adapter, REG_RXPKT_NUM,
+			(rtw_read32(adapter,REG_RXPKT_NUM)&(~RW_RELEASE_EN)));
+}
+
+static void rtw_hal_disable_tx_report(_adapter *adapter)
+{
+	rtw_write8(adapter, REG_TX_RPT_CTRL,
+			((rtw_read8(adapter, REG_TX_RPT_CTRL)&~BIT(1)))&~BIT(5));
+	DBG_871X("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
+}
+
+static void rtw_hal_enable_tx_report(_adapter *adapter)
+{
+	rtw_write8(adapter, REG_TX_RPT_CTRL,
+			((rtw_read8(adapter, REG_TX_RPT_CTRL)|BIT(1)))|BIT(5));
+	DBG_871X("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
+}
+
+static void rtw_hal_release_rx_dma(_adapter *adapter)
+{
+	u32 val32 = 0;
+
+	val32 = rtw_read32(adapter, REG_RXPKT_NUM);
+
+	rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
+
+	DBG_871X("%s, [0x%04x]: 0x%08x\n",
+		 __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
+}
+
+static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
+{
+	u8 ret = 0;
+	s8 trycnt = 100;
+	u16 len = 0;
+	u32 tmp = 0;
+	int res = 0;
+	//RX DMA stop
+	DBG_871X_LEVEL(_drv_always_, "Pause DMA\n");
+	rtw_write32(adapter, REG_RXPKT_NUM,
+			(rtw_read32(adapter,REG_RXPKT_NUM)|RW_RELEASE_EN));
+	do{
+		if((rtw_read32(adapter, REG_RXPKT_NUM)&RXDMA_IDLE)) {
+			DBG_871X_LEVEL(_drv_always_, "RX_DMA_IDLE is true\n");
+			ret = _SUCCESS;
+			break;
+		}
+#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+		else {
+			// If RX_DMA is not idle, receive one pkt from DMA
+			res = sdio_local_read(adapter,
+					SDIO_REG_RX0_REQ_LEN, 4, (u8*)&tmp);
+			len = le16_to_cpu(tmp);
+			DBG_871X_LEVEL(_drv_always_, "RX len:%d\n", len);
+
+			if (len > 0)
+				res = RecvOnePkt(adapter, len);
+			else
+				DBG_871X_LEVEL(_drv_always_, "read length fail %d\n", len);
+
+			DBG_871X_LEVEL(_drv_always_,
+				       "RecvOnePkt Result: %d\n", res);
+		}
+#endif //CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
+#ifdef CONFIG_USB_HCI
+		else {
+			if (adapter->intf_start)
+				adapter->intf_start(adapter);
+			tmp = rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE;
+			if (tmp) {
+				if (adapter->intf_stop)
+					adapter->intf_stop(adapter);
+				RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
+				RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
+			}
+		}
+#endif
+	}while(trycnt--);
+
+	if (trycnt < 0) {
+		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 3);
+
+		DBG_871X_LEVEL(_drv_always_, "Stop RX DMA failed......\n");
+		DBG_871X_LEVEL(_drv_always_, "%s, RXPKT_NUM: 0x%04x\n",
+				__func__, tmp);
+		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
+		if (tmp & BIT(3))
+			DBG_871X_LEVEL(_drv_always_, "%s, RX DMA has req\n",
+				       __func__);
+		else
+			DBG_871X_LEVEL(_drv_always_, "%s, RX DMA no req\n",
+				       __func__);
+		ret = _FAIL;
+	}
+
+	return ret;
+}
+
+#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+static u8 rtw_hal_enable_cpwm2(_adapter* adapter)
+{
+	u8 ret = 0;
+	int res = 0;
+	u32 tmp = 0;
+
+	DBG_871X_LEVEL(_drv_always_, "%s\n", __func__);
+
+	res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
+	if (!res)
+		DBG_871X_LEVEL(_drv_info_, "read SDIO_REG_HIMR: 0x%08x\n", tmp);
+	else
+		DBG_871X_LEVEL(_drv_info_, "sdio_local_read fail\n");
+
+	tmp = SDIO_HIMR_CPWM2_MSK;
+
+	res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
+
+	if (!res){
+		res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
+		DBG_871X_LEVEL(_drv_info_, "read again SDIO_REG_HIMR: 0x%08x\n", tmp);
+		ret = _SUCCESS;
+	}else {
+		DBG_871X_LEVEL(_drv_info_, "sdio_local_write fail\n");
+		ret = _FAIL;
+	}
+
+	return ret;
+}
+#endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
+#endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
+
+#ifdef CONFIG_WOWLAN
+/* 
+ * rtw_hal_check_wow_ctrl
+ * chk_type: _TRUE means to check enable, if 0x690 & bit1, WOW enable successful
+ *		     _FALSE means to check disable, if 0x690 & bit1, WOW disable fail
+ */
+static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
+{
+	u8 mstatus = 0;
+	u8 trycnt = 25;
+	u8 res = _FALSE;
+
+	mstatus = rtw_read8(adapter, REG_WOW_CTRL);
+	DBG_871X_LEVEL(_drv_info_, "%s mstatus:0x%02x\n", __func__, mstatus);
+
+	if (chk_type) {
+		while (!(mstatus&BIT1) && trycnt > 1) {
+			mstatus = rtw_read8(adapter, REG_WOW_CTRL);
+			DBG_871X_LEVEL(_drv_always_,
+					"Loop index: %d :0x%02x\n",
+					trycnt, mstatus);
+			trycnt--;
+			rtw_msleep_os(20);
+		}
+		if (mstatus & BIT1)
+			res = _TRUE;
+		else
+			res = _FALSE;
+	} else {
+		while (mstatus&BIT1 && trycnt > 1) {
+			mstatus = rtw_read8(adapter, REG_WOW_CTRL);
+			DBG_871X_LEVEL(_drv_always_,
+					"Loop index: %d :0x%02x\n",
+					trycnt, mstatus);
+			trycnt--;
+			rtw_msleep_os(20);
+		}
+
+		if (mstatus & BIT1)
+			res = _FALSE;
+		else
+			res = _TRUE;
+	}
+	DBG_871X_LEVEL(_drv_always_, "%s check_type: %d res: %d trycnt: %d\n",
+			__func__, chk_type, res, (25 - trycnt));
+	return res;
+}
+
+#ifdef CONFIG_PNO_SUPPORT
+static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
+{
+	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
+	u8 res = 0, count = 0;
+	u8 ret = _FALSE;
+	
+	if (ppwrpriv->wowlan_pno_enable && ppwrpriv->pno_in_resume == _FALSE) {
+		res = rtw_read8(adapter, REG_PNO_STATUS);
+		while (!(res&BIT(7)) && count < 25) {
+			DBG_871X("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
+					count, res);
+			res = rtw_read8(adapter, REG_PNO_STATUS);
+			count++;
+			rtw_msleep_os(2);
+		}
+		if (res & BIT(7))
+			ret = _TRUE;
+		else
+			ret = _FALSE;
+		DBG_871X("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
+	}
+	return ret;
+}
+#endif
+
+static void rtw_hal_backup_rate(_adapter *adapter)
+{
+	DBG_871X("%s\n", __func__);
+	/* backup data rate to register 0x8b for wowlan FW */
+	rtw_write8(adapter, 0x8d, 1);
+	rtw_write8(adapter, 0x8c, 0);
+	rtw_write8(adapter, 0x8f, 0x40);
+	rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
+}
+
+#ifdef CONFIG_GTK_OL
+static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
+{
+	struct security_priv *psecuritypriv = &adapter->securitypriv;
+	u8 null_addr[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+	int cam_id;
+	u32 algorithm = 0;
+	u16 ctrl = 0;
+	u8 *addr;
+	u8 index = 0;
+	u8 get_key[16];
+
+	addr = get_bssid(&adapter->mlmepriv);
+
+	if (addr == NULL) {
+		DBG_871X("%s: get bssid MAC addr fail!!\n", __func__);
+		return;
+	}
+
+	do{
+		cam_id = rtw_camid_search(adapter, addr, index, -1);
+		if (cam_id == -1) {
+			DBG_871X("%s: cam_id: %d, key_id:%d\n",
+					__func__, cam_id, index);
+		} else if (rtw_camid_is_gk(adapter, cam_id) != _TRUE) {
+			DBG_871X("%s: cam_id: %d key_id(%d) is not GK\n",
+					__func__, cam_id, index);
+		} else {
+			rtw_sec_read_cam_ent(adapter, cam_id, NULL, NULL, get_key);
+			algorithm = psecuritypriv->dot11PrivacyAlgrthm;
+			ctrl = BIT(15) | BIT6 |(algorithm << 2) | index;
+			write_cam(adapter, index, ctrl, addr, get_key);
+			ctrl = 0;
+			write_cam(adapter, cam_id, ctrl, null_addr, get_key);
+		}
+		index++;
+	}while(index < 4);
+
+	rtw_write8(adapter, REG_SECCFG, 0xcc);
+}
+
+static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
+{
+	struct security_priv *psecuritypriv = &adapter->securitypriv;
+	u8 default_cam_id = 0;
+	u8 cam_id=5;
+	u8 *addr;
+	u8 null_addr[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+	u8 gtk_keyindex=0;
+	u8 get_key[16];
+	u8 index = 1;
+	u16 ctrl = 0;
+	u32 algorithm = 0;
+
+	addr = get_bssid(&adapter->mlmepriv);
+
+	if (addr == NULL) {
+		DBG_871X("%s: get bssid MAC addr fail!!\n", __func__);
+		return;
+	}
+
+	_rtw_memset(get_key, 0, sizeof(get_key));
+
+	algorithm = psecuritypriv->dot11PrivacyAlgrthm;
+
+	if(psecuritypriv->binstallKCK_KEK == _TRUE) {
+
+		//read gtk key index
+		gtk_keyindex = rtw_read8(adapter, 0x48c);
+		do{
+			/* chech if GK */
+			if (rtw_sec_read_cam_is_gk(adapter, default_cam_id) == _TRUE) {
+				rtw_sec_read_cam_ent(adapter, default_cam_id, NULL, NULL, get_key);
+				algorithm = psecuritypriv->dot11PrivacyAlgrthm;
+				/* in default cam entry, cam id = key id */
+				ctrl = BIT(15) | BIT6 | (algorithm << 2) | default_cam_id;
+				write_cam(adapter, cam_id, ctrl, addr, get_key);
+				cam_id++;
+				ctrl = 0;
+				write_cam(adapter, default_cam_id, ctrl, null_addr, get_key);
+			}
+
+			if (gtk_keyindex < 4 && (default_cam_id == gtk_keyindex)) {
+				psecuritypriv->dot118021XGrpKeyid = gtk_keyindex;
+				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey,
+						get_key, 16);
+
+				DBG_871X_LEVEL(_drv_always_, "GTK (%d) = 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+						gtk_keyindex,
+				psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[0], 
+				psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[1],
+				psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[2],
+				psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[3]);
+			}
+			default_cam_id++;
+		} while (default_cam_id < 4);
+
+		rtw_write8(adapter, REG_SECCFG, 0x0c);
+#ifdef CONFIG_GTK_OL_DBG
+		//if (gtk_keyindex != 5)
+		dump_sec_cam(RTW_DBGDUMP, adapter);
+#endif
+	}
+}
+#endif
+
+static void rtw_hal_update_tx_iv(_adapter *adapter)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+	u64 iv_low = 0, iv_high = 0;
+
+	// 3.1 read fw iv
+	iv_low = rtw_read32(adapter, REG_TXPKTBUF_IV_LOW);
+	//only low two bytes is PN, check AES_IV macro for detail
+	iv_low &= 0xffff;
+	iv_high = rtw_read32(adapter, REG_TXPKTBUF_IV_HIGH);
+	//get the real packet number
+	pwrctl->wowlan_fw_iv = iv_high << 16 | iv_low;
+	DBG_871X_LEVEL(_drv_always_,
+			"fw_iv: 0x%016llx\n", pwrctl->wowlan_fw_iv);
+	//Update TX iv data.
+	rtw_set_sec_pn(adapter);
+}
+
+static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
+{
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+
+	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN]={0};
+	u8 adopt = 1, check_period = 5;
+	u8 ret = _FAIL;
+
+	DBG_871X("%s(): enable = %d\n", __func__, enable);
+	SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
+	SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
+	SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
+	SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_KEEP_ALIVE,
+				H2C_KEEP_ALIVE_CTRL_LEN,
+				u1H2CKeepAliveParm);
+
+	return ret;
+}
+
+static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
+{
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN]={0};
+	u8 adopt = 1, check_period = 10, trypkt_num = 0;
+	u8 ret = _FAIL;
+
+	DBG_871X("%s(): enable = %d\n", __func__, enable);
+	SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
+	SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
+	SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
+	SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_DISCON_DECISION,
+				H2C_DISCON_DECISION_LEN,
+				u1H2CDisconDecisionParm);
+	return ret;
+}
+
+static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
+{
+	struct security_priv *psecpriv = &adapter->securitypriv;
+	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+
+	u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN]={0};
+	u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
+	u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
+	u8 sdio_wakeup_enable = 1;
+	u8 gpio_high_active = 0;
+	u8 pattern_en = 0;
+	u8 magic_pkt = 0;
+	u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
+	u8 ret = _FAIL;
+
+#ifdef CONFIG_GPIO_WAKEUP
+	gpio_high_active = ppwrpriv->is_high_active;
+	gpionum = WAKEUP_GPIO_IDX;
+	sdio_wakeup_enable = 0;
+#endif //CONFIG_GPIO_WAKEUP
+
+	if (!ppwrpriv->wowlan_pno_enable)
+		magic_pkt = enable;
+
+	if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_)
+		hw_unicast = 1;
+	else
+		hw_unicast = 0;
+
+	if (ppwrpriv->wowlan_pattern) {
+		if (enable)
+			pattern_en = 1;
+		else
+			pattern_en = 0;
+	}
+
+	DBG_871X("%s(): enable=%d change_unit=%d\n", __func__,
+			enable, change_unit);
+
+	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
+	if (enable && change_unit) {
+		gpio_dur = 0x40;
+		gpio_unit = 1;
+		gpio_pulse_en = 1;
+	}
+
+#ifdef CONFIG_PLATFORM_ARM_RK3188
+	if (enable) {
+		gpio_pulse_en = 1;
+		gpio_pulse_cnt = 0x04;
+	}
+#endif
+
+	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
+	SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, pattern_en);
+	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
+	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
+	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
+	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
+#ifndef CONFIG_GTK_OL
+	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
+#endif
+	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
+	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
+	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
+
+	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
+	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
+
+	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
+	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_WOWLAN,
+				H2C_WOWLAN_LEN,
+				u1H2CWoWlanCtrlParm);
+	return ret;
+}
+
+static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
+{
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	struct security_priv* psecuritypriv=&(adapter->securitypriv);
+	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
+	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN]={0};
+	u8 ret = _FAIL, count = 0;
+
+	DBG_871X("%s(): enable=%d\n", __func__, enable);
+
+	if (!ppwrpriv->wowlan_pno_enable) {
+		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
+				u1H2CRemoteWakeCtrlParm, enable);
+		SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
+				u1H2CRemoteWakeCtrlParm, 1);
+#ifdef CONFIG_GTK_OL
+		if (psecuritypriv->binstallKCK_KEK == _TRUE &&
+				psecuritypriv->dot11PrivacyAlgrthm == _AES_) {
+			SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
+					u1H2CRemoteWakeCtrlParm, 1);
+		} else {
+			DBG_871X("no kck or security is not AES\n");
+			SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
+					u1H2CRemoteWakeCtrlParm, 0);
+		}
+#endif //CONFIG_GTK_OL
+
+		SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
+						u1H2CRemoteWakeCtrlParm,
+						!ppwrpriv->wowlan_pattern);
+
+		/*
+		 * filter NetBios name service pkt to avoid being waked-up
+		 * by this kind of unicast pkt this exceptional modification 
+		 * is used for match competitor's behavior
+		 */
+		SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
+				u1H2CRemoteWakeCtrlParm, !ppwrpriv->wowlan_pattern);
+		
+		if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
+			(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
+			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
+					u1H2CRemoteWakeCtrlParm, 0);
+		} else {
+			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
+					u1H2CRemoteWakeCtrlParm, 1);
+		}
+
+		SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
+			u1H2CRemoteWakeCtrlParm, 1);
+	}
+#ifdef CONFIG_PNO_SUPPORT
+	else {
+		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
+				u1H2CRemoteWakeCtrlParm, enable);
+		SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
+				u1H2CRemoteWakeCtrlParm, enable);
+	}
+#endif
+
+#ifdef CONFIG_P2P_WOWLAN
+	if (_TRUE == ppwrpriv->wowlan_p2p_mode)
+	{
+		DBG_871X("P2P OFFLOAD ENABLE\n");
+		SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm,1);
+	}
+	else
+	{
+		DBG_871X("P2P OFFLOAD DISABLE\n");
+		SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm,0);
+	}
+#endif //CONFIG_P2P_WOWLAN
+
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_REMOTE_WAKE_CTRL,
+				H2C_REMOTE_WAKE_CTRL_LEN,
+				u1H2CRemoteWakeCtrlParm);
+	return ret;
+}
+
+static u8 rtw_hal_set_global_info_cmd(_adapter* adapter, u8 group_alg, u8 pairwise_alg)
+{
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	u8 ret = _FAIL;
+	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN]={0};
+
+	DBG_871X("%s(): group_alg=%d pairwise_alg=%d\n",
+			__func__, group_alg, pairwise_alg);
+	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
+			pairwise_alg);
+	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
+			group_alg);
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_AOAC_GLOBAL_INFO,
+				H2C_AOAC_GLOBAL_INFO_LEN,
+				u1H2CAOACGlobalInfoParm);
+
+	return ret;
+}
+
+#ifdef CONFIG_PNO_SUPPORT
+static u8 rtw_hal_set_scan_offload_info_cmd(_adapter* adapter,
+		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
+{
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+
+	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN]={0};
+	u8 res = 0, count = 0, ret = _FAIL;
+
+	DBG_871X("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
+		__func__, rsvdpageloc->LocProbePacket,
+		rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
+
+	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
+	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
+	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
+			rsvdpageloc->LocScanInfo);
+	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
+			rsvdpageloc->LocProbePacket);
+	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
+			rsvdpageloc->LocSSIDInfo);
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_D0_SCAN_OFFLOAD_INFO,
+				H2C_SCAN_OFFLOAD_CTRL_LEN,
+				u1H2CScanOffloadInfoParm);
+	return ret;
+}
+#endif //CONFIG_PNO_SUPPORT
+
+void rtw_hal_set_fw_wow_related_cmd(_adapter* padapter, u8 enable)
+{
+	struct security_priv *psecpriv = &padapter->securitypriv;
+	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	struct sta_info *psta = NULL;
+	u16 media_status_rpt;
+	u8	pkt_type = 0;
+	u8 ret = _SUCCESS;
+
+	DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable);
+_func_enter_;
+
+	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
+
+	if (enable) {
+		rtw_hal_set_global_info_cmd(padapter,
+				psecpriv->dot118021XGrpPrivacy,
+				psecpriv->dot11PrivacyAlgrthm);
+
+		if (!(ppwrpriv->wowlan_pno_enable)) {
+			rtw_hal_set_disconnect_decision_cmd(padapter, enable);
+#ifdef CONFIG_ARP_KEEP_ALIVE
+			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
+				(psecpriv->dot11PrivacyAlgrthm == _WEP104_))
+				pkt_type = 0;
+			else
+				pkt_type = 1;
+#else
+			pkt_type = 0;
+#endif //CONFIG_ARP_KEEP_ALIVE
+			rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
+		}
+		rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
+#ifdef CONFIG_PNO_SUPPORT
+		rtw_hal_check_pno_enabled(padapter);
+#endif //CONFIG_PNO_SUPPORT
+	} else {
+#if 0
+		{
+			u32 PageSize = 0;
+			rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
+			dump_TX_FIFO(padapter, 4, PageSize);
+		}
+#endif
+
+		rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
+	}
+_func_exit_;
+	DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);
+}
+#endif //CONFIG_WOWLAN
+
+#ifdef CONFIG_AP_WOWLAN
+static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
+{
+	struct security_priv *psecpriv = &adapter->securitypriv;
+	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+
+	u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
+	u8 gpionum = 0, gpio_dur = 0;
+	u8 gpio_pulse = enable;
+	u8 sdio_wakeup_enable = 1;
+	u8 gpio_high_active = 0;
+	u8 ret = _FAIL;
+
+#ifdef CONFIG_GPIO_WAKEUP
+	gpio_high_active = ppwrpriv->is_high_active;
+	gpionum = WAKEUP_GPIO_IDX;
+	sdio_wakeup_enable = 0;
+#endif /*CONFIG_GPIO_WAKEUP*/
+
+	DBG_871X("%s(): enable=%d\n", __func__, enable);
+
+	SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
+			gpionum);
+	SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
+			gpio_pulse);
+	SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
+			gpio_high_active);
+	SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
+			enable);
+	SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
+			gpio_dur);
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_AP_WOW_GPIO_CTRL,
+				H2C_AP_WOW_GPIO_CTRL_LEN,
+				u1H2CAPWoWlanCtrlParm);
+
+	return ret;
+}
+
+static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
+{
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
+	u8 ret = _FAIL;
+
+	DBG_871X("%s(): bFuncEn=%d\n", __func__, enable);
+
+	SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_AP_OFFLOAD,
+				H2C_AP_OFFLOAD_LEN,
+				u1H2CAPOffloadCtrlParm);
+
+	return ret;
+}
+
+static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
+{
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
+	u8 ret = _FAIL;
+
+	DBG_871X("%s(): enable=%d\n" , __func__ , enable);
+	
+	SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
+#ifndef CONFIG_USB_HCI
+	SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
+#endif /*CONFIG_USB_HCI*/
+	SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
+	
+	if (enable)
+		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
+	else
+		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
+		
+	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
+			H2C_AP_PS_LEN, ap_ps_parm);
+
+	return ret;
+}
+
+static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
+		PRSVDPAGE_LOC rsvdpageloc)
+{
+	struct hal_ops *pHalFunc = &padapter->HalFunc;
+	u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
+	u8 ret = _FAIL, header = 0;
+
+	if (pHalFunc->fill_h2c_cmd == NULL) {
+		DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
+		return;
+	}
+
+	header = rtw_read8(padapter, REG_BCNQ_BDNY);
+
+	DBG_871X("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
+			rsvdpageloc->LocApOffloadBCN,
+			rsvdpageloc->LocProbeRsp,
+			header);
+
+	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
+			rsvdpageloc->LocApOffloadBCN + header);
+
+	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
+				H2C_BCN_RSVDPAGE_LEN, rsvdparm);
+
+	if (ret == _FAIL)
+		DBG_871X("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
+
+	rtw_msleep_os(10);
+
+	_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
+
+	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
+			rsvdpageloc->LocProbeRsp + header);
+
+	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
+				H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
+
+	if (ret == _FAIL)
+		DBG_871X("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
+
+	rtw_msleep_os(10);
+}
+
+static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
+{
+	rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
+	rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
+	rtw_hal_set_ap_ps_cmd(padapter, enable);
+}
+
+static void rtw_hal_ap_wow_enable(_adapter *padapter)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+	struct security_priv *psecuritypriv = &padapter->securitypriv;
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+	struct hal_ops *pHalFunc = &padapter->HalFunc;
+	struct sta_info *psta = NULL;
+#ifdef DBG_CHECK_FW_PS_STATE
+	struct dvobj_priv *psdpriv = padapter->dvobj;
+	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+#endif /*DBG_CHECK_FW_PS_STATE*/
+	int res;
+	u16 media_status_rpt;
+
+	DBG_871X("%s, WOWLAN_AP_ENABLE\n", __func__);
+#ifdef DBG_CHECK_FW_PS_STATE
+	if (rtw_fw_ps_state(padapter) == _FAIL) {
+		pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
+		DBG_871X_LEVEL(_drv_always_, "wowlan enable no leave 32k\n");
+	}
+#endif /*DBG_CHECK_FW_PS_STATE*/
+
+	/* 1. Download WOWLAN FW*/
+	rtw_hal_fw_dl(padapter, _TRUE);
+
+	media_status_rpt = RT_MEDIA_CONNECT;
+	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
+		(u8 *)&media_status_rpt);
+
+	issue_beacon(padapter, 0);
+
+	rtw_msleep_os(2);
+
+	if (IS_HARDWARE_TYPE_8188E(padapter))
+		rtw_hal_disable_tx_report(padapter);
+
+	/* RX DMA stop */
+	res = rtw_hal_pause_rx_dma(padapter);
+	if (res == _FAIL)
+		DBG_871X_LEVEL(_drv_always_, "[WARNING] pause RX DMA fail\n");
+
+#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+	/* Enable CPWM2 only. */
+	res = rtw_hal_enable_cpwm2(padapter);
+	if (res == _FAIL)
+		DBG_871X_LEVEL(_drv_always_, "[WARNING] enable cpwm2 fail\n");
+#endif
+
+#ifdef CONFIG_GPIO_WAKEUP
+	rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
+#endif
+	/* 5. Set Enable WOWLAN H2C command. */
+	DBG_871X_LEVEL(_drv_always_, "Set Enable AP WOWLan cmd\n");
+	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
+		
+	rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
+#ifdef CONFIG_USB_HCI 
+	if (padapter->intf_stop)
+		padapter->intf_stop(padapter);
+#ifdef CONFIG_CONCURRENT_MODE
+	if (rtw_buddy_adapter_up(padapter))/*free buddy adapter's resource*/
+		padapter->pbuddy_adapter->intf_stop(padapter->pbuddy_adapter);
+#endif /*CONFIG_CONCURRENT_MODE*/
+		/* Invoid SE0 reset signal during suspending*/
+	rtw_write8(padapter, REG_RSV_CTRL, 0x20);
+	rtw_write8(padapter, REG_RSV_CTRL, 0x60);
+#endif /*CONFIG_USB_HCI*/
+}
+
+static void rtw_hal_ap_wow_disable(_adapter *padapter)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+	struct hal_ops *pHalFunc = &padapter->HalFunc;
+#ifdef DBG_CHECK_FW_PS_STATE
+	struct dvobj_priv *psdpriv = padapter->dvobj;
+	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+#endif /*DBG_CHECK_FW_PS_STATE*/
+	u16 media_status_rpt;
+	u8 val8;
+
+	DBG_871X("%s, WOWLAN_AP_DISABLE\n", __func__);
+	/* 1. Read wakeup reason*/
+	pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
+
+	DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x\n",
+		pwrctl->wowlan_wake_reason);
+
+	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
+
+	rtw_msleep_os(2);
+#ifdef DBG_CHECK_FW_PS_STATE
+	if (rtw_fw_ps_state(padapter) == _FAIL) {
+		pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
+		DBG_871X_LEVEL(_drv_always_, "wowlan enable no leave 32k\n");
+	}
+#endif /*DBG_CHECK_FW_PS_STATE*/
+
+	if (IS_HARDWARE_TYPE_8188E(padapter))
+		rtw_hal_enable_tx_report(padapter);
+
+	rtw_hal_force_enable_rxdma(padapter);
+
+	rtw_hal_fw_dl(padapter, _FALSE);
+
+#ifdef CONFIG_GPIO_WAKEUP
+	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
+	DBG_871X_LEVEL(_drv_always_, "Set Wake GPIO to default(%d).\n", val8);
+	rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
+	rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE);
+#endif
+	media_status_rpt = RT_MEDIA_CONNECT;
+
+	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
+				(u8 *)&media_status_rpt);
+
+	issue_beacon(padapter, 0);
+}
+#endif /*CONFIG_AP_WOWLAN*/
+
+#ifdef CONFIG_P2P_WOWLAN
+static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
+{
+	u8 *ssid_ie;
+	sint ssid_len_ori;
+	int len_diff = 0;
+	
+	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
+
+	//DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
+	
+	if(ssid_ie && ssid_len_ori>0)
+	{
+		switch(hidden_ssid_mode)
+		{
+			case 1:
+			{
+				u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
+				u32 remain_len = 0;
+				
+				remain_len = ies_len -(next_ie-ies);
+				
+				ssid_ie[1] = 0;				
+				_rtw_memcpy(ssid_ie+2, next_ie, remain_len);
+				len_diff -= ssid_len_ori;
+				
+				break;
+			}		
+			case 2:
+				_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
+				break;
+			default:
+				break;
+		}
+	}
+
+	return len_diff;
+}
+
+static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+	//struct xmit_frame	*pmgntframe;
+	//struct pkt_attrib	*pattrib;
+	//unsigned char	*pframe;
+	struct rtw_ieee80211_hdr *pwlanhdr;
+	unsigned short *fctrl;
+	unsigned int	rate_len;
+	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
+	u32	pktlen;
+//#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
+//	_irqL irqL;
+//	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+//#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
+	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
+	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+#ifdef CONFIG_P2P
+	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
+#endif //CONFIG_P2P
+
+	//for debug
+	u8 *dbgbuf = pframe;
+	u8 dbgbufLen = 0, index = 0;
+
+	DBG_871X("%s\n", __FUNCTION__);
+//#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
+//	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
+//#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
+		
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;	
+	
+	
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+	
+	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
+	//pmlmeext->mgnt_seq++;
+	SetFrameSubType(pframe, WIFI_BEACON);
+	
+	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);	
+	pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
+	
+	if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
+	{
+		//DBG_871X("ie len=%d\n", cur_network->IELength);
+#ifdef CONFIG_P2P
+		// for P2P : Primary Device Type & Device Name
+		u32 wpsielen=0, insert_len=0;
+		u8 *wpsie=NULL;		
+		wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
+		
+		if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
+		{
+			uint wps_offset, remainder_ielen;
+			u8 *premainder_ie, *pframe_wscie;
+	
+			wps_offset = (uint)(wpsie - cur_network->IEs);
+
+			premainder_ie = wpsie + wpsielen;
+
+			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
+
+#ifdef CONFIG_IOCTL_CFG80211
+			if(pwdinfo->driver_interface == DRIVER_CFG80211 )
+			{
+				if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
+				{
+					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
+					pframe += wps_offset;
+					pktlen += wps_offset;
+
+					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
+					pframe += pmlmepriv->wps_beacon_ie_len;
+					pktlen += pmlmepriv->wps_beacon_ie_len;
+
+					//copy remainder_ie to pframe
+					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
+					pframe += remainder_ielen;		
+					pktlen += remainder_ielen;
+				}
+				else
+				{
+					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
+					pframe += cur_network->IELength;
+					pktlen += cur_network->IELength;
+				}
+			}
+			else
+#endif //CONFIG_IOCTL_CFG80211
+			{
+				pframe_wscie = pframe + wps_offset;
+				_rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);			
+				pframe += (wps_offset + wpsielen);		
+				pktlen += (wps_offset + wpsielen);
+
+				//now pframe is end of wsc ie, insert Primary Device Type & Device Name
+				//	Primary Device Type
+				//	Type:
+				*(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
+				insert_len += 2;
+				
+				//	Length:
+				*(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
+				insert_len += 2;
+				
+				//	Value:
+				//	Category ID
+				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
+				insert_len += 2;
+
+				//	OUI
+				*(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
+				insert_len += 4;
+
+				//	Sub Category ID
+				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
+				insert_len += 2;
+
+
+				//	Device Name
+				//	Type:
+				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
+				insert_len += 2;
+
+				//	Length:
+				*(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
+				insert_len += 2;
+
+				//	Value:
+				_rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
+				insert_len += pwdinfo->device_name_len;
+
+
+				//update wsc ie length
+				*(pframe_wscie+1) = (wpsielen -2) + insert_len;
+
+				//pframe move to end
+				pframe+=insert_len;
+				pktlen += insert_len;
+
+				//copy remainder_ie to pframe
+				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
+				pframe += remainder_ielen;		
+				pktlen += remainder_ielen;
+			}
+		}
+		else
+#endif //CONFIG_P2P
+		{
+			int len_diff;
+			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
+			len_diff = update_hidden_ssid(
+				pframe+_BEACON_IE_OFFSET_
+				, cur_network->IELength-_BEACON_IE_OFFSET_
+				, pmlmeinfo->hidden_ssid_mode
+			);
+			pframe += (cur_network->IELength+len_diff);
+			pktlen += (cur_network->IELength+len_diff);
+		}
+#if 0
+		{
+			u8 *wps_ie;
+			uint wps_ielen;
+			u8 sr = 0;
+			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
+				pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
+			if (wps_ie && wps_ielen>0) {
+				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
+			}
+			if (sr != 0)
+				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
+			else
+				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
+		}
+#endif 
+#ifdef CONFIG_P2P
+		if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
+		{
+			u32 len;
+#ifdef CONFIG_IOCTL_CFG80211
+			if(pwdinfo->driver_interface == DRIVER_CFG80211 )
+			{
+				len = pmlmepriv->p2p_beacon_ie_len;
+				if(pmlmepriv->p2p_beacon_ie && len>0)				
+					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
+			}
+			else
+#endif //CONFIG_IOCTL_CFG80211
+			{
+				len = build_beacon_p2p_ie(pwdinfo, pframe);
+			}
+
+			pframe += len;
+			pktlen += len;
+
+			#ifdef CONFIG_WFD
+			len = rtw_append_beacon_wfd_ie(padapter, pframe);
+			pframe += len;
+			pktlen += len;
+			#endif
+
+		}
+#endif //CONFIG_P2P
+
+		goto _issue_bcn;
+
+	}
+
+	//below for ad-hoc mode
+
+	//timestamp will be inserted by hardware
+	pframe += 8;
+	pktlen += 8;
+
+	// beacon interval: 2 bytes
+
+	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 
+
+	pframe += 2;
+	pktlen += 2;
+
+	// capability info: 2 bytes
+
+	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
+
+	pframe += 2;
+	pktlen += 2;
+
+	// SSID
+	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
+
+	// supported rates...
+	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
+	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
+
+	// DS parameter set
+	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
+
+	//if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
+	{
+		u8 erpinfo=0;
+		u32 ATIMWindow;
+		// IBSS Parameter Set...
+		//ATIMWindow = cur->Configuration.ATIMWindow;
+		ATIMWindow = 0;
+		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
+
+		//ERP IE
+		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
+	}	
+
+
+	// EXTERNDED SUPPORTED RATE
+	if (rate_len > 8)
+	{
+		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
+	}
+
+
+	//todo:HT for adhoc
+
+_issue_bcn:
+
+//#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
+//	pmlmepriv->update_bcn = _FALSE;
+//	
+//	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);	
+//#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
+
+	*pLength = pktlen;
+#if 0
+	// printf dbg msg
+	dbgbufLen = pktlen;
+	DBG_871X("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
+
+	for(index=0;index<dbgbufLen;index++)
+		printk("%x ",*(dbgbuf+index));
+
+	printk("\n");
+	DBG_871X("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
+	
+#endif
+}
+
+static int get_reg_classes_full_count(struct p2p_channels channel_list) {
+	int cnt = 0;
+	int i;
+
+	for (i = 0; i < channel_list.reg_classes; i++) {
+		cnt += channel_list.reg_class[i].channels;
+	}
+
+	return cnt;
+}
+
+static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+	//struct xmit_frame			*pmgntframe;
+	//struct pkt_attrib			*pattrib;
+	//unsigned char					*pframe;
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	unsigned short				*fctrl;	
+	unsigned char					*mac;
+	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	//WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
+	u16					beacon_interval = 100;
+	u16					capInfo = 0;
+	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
+	u8					wpsie[255] = { 0x00 };
+	u32					wpsielen = 0, p2pielen = 0;
+	u32					pktlen;
+#ifdef CONFIG_WFD
+	u32					wfdielen = 0;
+#endif
+#ifdef CONFIG_INTEL_WIDI
+	u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
+#endif //CONFIG_INTEL_WIDI
+
+	//for debug
+	u8 *dbgbuf = pframe;
+	u8 dbgbufLen = 0, index = 0;
+
+	DBG_871X("%s\n", __FUNCTION__);
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;	
+	
+	mac = adapter_mac_addr(padapter);
+	
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+
+	//DA filled by FW
+	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
+	
+	//	Use the device address for BSSID field.	
+	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0);
+	SetFrameSubType(fctrl, WIFI_PROBERSP);
+
+ 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ 	pframe += pktlen;
+
+
+	//timestamp will be inserted by hardware
+	pframe += 8;
+	pktlen += 8;
+
+	// beacon interval: 2 bytes
+	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2); 
+	pframe += 2;
+	pktlen += 2;
+
+	//	capability info: 2 bytes
+	//	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
+	capInfo |= cap_ShortPremble;
+	capInfo |= cap_ShortSlot;
+	
+	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
+	pframe += 2;
+	pktlen += 2;
+
+
+	// SSID
+	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
+
+	// supported rates...
+	//	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
+	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
+
+	// DS parameter set
+	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
+
+#ifdef CONFIG_IOCTL_CFG80211
+	if(pwdinfo->driver_interface == DRIVER_CFG80211 )
+	{
+		if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
+		{
+			//WPS IE
+			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
+			pktlen += pmlmepriv->wps_probe_resp_ie_len;
+			pframe += pmlmepriv->wps_probe_resp_ie_len;
+
+			//P2P IE
+			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
+			pktlen += pmlmepriv->p2p_probe_resp_ie_len;
+			pframe += pmlmepriv->p2p_probe_resp_ie_len;
+		}
+	}
+	else
+#endif //CONFIG_IOCTL_CFG80211		
+	{
+
+		//	Todo: WPS IE
+		//	Noted by Albert 20100907
+		//	According to the WPS specification, all the WPS attribute is presented by Big Endian.
+
+		wpsielen = 0;
+		//	WPS OUI
+		*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
+		wpsielen += 4;
+
+		//	WPS version
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
+		wpsielen += 2;
+
+		//	Value:
+		wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
+
+#ifdef CONFIG_INTEL_WIDI
+		//	Commented by Kurt
+		//	Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
+		if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE 
+			|| pmlmepriv->num_p2p_sdt != 0 )
+		{
+			//Sec dev type
+			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
+			wpsielen += 2;
+
+			//	Length:
+			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
+			wpsielen += 2;
+
+			//	Value:
+			//	Category ID
+			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
+			wpsielen += 2;
+
+			//	OUI
+			*(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
+			wpsielen += 4;
+
+			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
+			wpsielen += 2;
+
+			if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
+			{
+				//	Vendor Extension
+				_rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
+				wpsielen += L2SDTA_SERVICE_VE_LEN;
+			}
+		}
+#endif //CONFIG_INTEL_WIDI
+
+		//	WiFi Simple Config State
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
+		wpsielen += 2;
+
+		//	Value:
+		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	//	Not Configured.
+
+		//	Response Type
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
+		wpsielen += 2;
+
+		//	Value:
+		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
+
+		//	UUID-E
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
+		wpsielen += 2;
+
+		//	Value:
+		if (pwdinfo->external_uuid == 0) {
+			_rtw_memset( wpsie + wpsielen, 0x0, 16 );
+			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
+		} else {
+			_rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
+		}
+		wpsielen += 0x10;
+
+		//	Manufacturer
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
+		wpsielen += 2;
+
+		//	Value:
+		_rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
+		wpsielen += 7;
+
+		//	Model Name
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
+		wpsielen += 2;	
+
+		//	Value:
+		_rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
+		wpsielen += 6;
+
+		//	Model Number
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
+		wpsielen += 2;
+
+		//	Value:
+		wpsie[ wpsielen++ ] = 0x31;		//	character 1
+
+		//	Serial Number
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
+		wpsielen += 2;
+
+		//	Value:
+		_rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
+		wpsielen += ETH_ALEN;
+
+		//	Primary Device Type
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
+		wpsielen += 2;
+
+		//	Value:
+		//	Category ID
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
+		wpsielen += 2;
+
+		//	OUI
+		*(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
+		wpsielen += 4;
+
+		//	Sub Category ID
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
+		wpsielen += 2;
+
+		//	Device Name
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
+		wpsielen += 2;
+
+		//	Value:
+		_rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
+		wpsielen += pwdinfo->device_name_len;
+
+		//	Config Method
+		//	Type:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
+		wpsielen += 2;
+
+		//	Length:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
+		wpsielen += 2;
+
+		//	Value:
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
+		wpsielen += 2;
+		
+
+		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen );
+		
+
+		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
+		pframe += p2pielen;
+		pktlen += p2pielen;
+	}
+
+#ifdef CONFIG_WFD
+	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
+	pframe += wfdielen;
+	pktlen += wfdielen;
+#endif
+
+	*pLength = pktlen;
+
+#if 0
+	// printf dbg msg
+	dbgbufLen = pktlen;
+	DBG_871X("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
+
+	for(index=0;index<dbgbufLen;index++)
+		printk("%x ",*(dbgbuf+index));
+
+	printk("\n");
+	DBG_871X("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
+#endif
+}
+static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
+	u8			action = P2P_PUB_ACTION_ACTION;
+	u32			p2poui = cpu_to_be32(P2POUI);
+	u8			oui_subtype = P2P_GO_NEGO_RESP;
+	u8			wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
+	u8			p2pielen = 0, i;
+	uint			wpsielen = 0;
+	u16			wps_devicepassword_id = 0x0000;
+	uint			wps_devicepassword_id_len = 0;
+	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
+	u16			len_channellist_attr = 0;
+	u32			pktlen;
+	u8			dialogToken = 0;
+	
+	//struct xmit_frame			*pmgntframe;
+	//struct pkt_attrib			*pattrib;
+	//unsigned char					*pframe;
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	unsigned short				*fctrl;
+	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
+	//WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
+
+#ifdef CONFIG_WFD
+	u32					wfdielen = 0;
+#endif
+
+	//for debug
+	u8 *dbgbuf = pframe;
+	u8 dbgbufLen = 0, index = 0;
+
+	DBG_871X( "%s\n", __FUNCTION__);
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+
+	//RA, filled by FW
+	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0);
+	SetFrameSubType(pframe, WIFI_ACTION);
+
+	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+	pframe += pktlen;
+
+	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));	
+	
+	//dialog token, filled by FW
+	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
+
+	_rtw_memset( wpsie, 0x00, 255 );
+	wpsielen = 0;
+
+	//	WPS Section
+	wpsielen = 0;
+	//	WPS OUI
+	*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
+	wpsielen += 4;
+
+	//	WPS version
+	//	Type:
+	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
+	wpsielen += 2;
+
+	//	Length:
+	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
+	wpsielen += 2;
+
+	//	Value:
+	wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
+
+	//	Device Password ID
+	//	Type:
+	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
+	wpsielen += 2;
+
+	//	Length:
+	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
+	wpsielen += 2;
+
+	//	Value:
+	if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
+	{
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
+	}
+	else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
+	{
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
+	}
+	else
+	{
+		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
+	}
+	wpsielen += 2;
+
+	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen );
+
+
+	//	P2P IE Section.
+
+	//	P2P OUI
+	p2pielen = 0;
+	p2pie[ p2pielen++ ] = 0x50;
+	p2pie[ p2pielen++ ] = 0x6F;
+	p2pie[ p2pielen++ ] = 0x9A;
+	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
+
+	//	Commented by Albert 20100908
+	//	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
+	//	1. Status
+	//	2. P2P Capability
+	//	3. Group Owner Intent
+	//	4. Configuration Timeout
+	//	5. Operating Channel
+	//	6. Intended P2P Interface Address
+	//	7. Channel List
+	//	8. Device Info
+	//	9. Group ID	( Only GO )
+
+
+	//	ToDo:
+
+	//	P2P Status
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
+	p2pielen += 2;
+
+	//	Value, filled by FW
+	p2pie[ p2pielen++ ] = 1;
+	
+	//	P2P Capability
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
+	p2pielen += 2;
+
+	//	Value:
+	//	Device Capability Bitmap, 1 byte
+
+	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
+	{
+		//	Commented by Albert 2011/03/08
+		//	According to the P2P specification
+		//	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
+		p2pie[ p2pielen++ ] = 0;
+	}
+	else
+	{
+		//	Be group owner or meet the error case
+		p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
+	}
+	
+	//	Group Capability Bitmap, 1 byte
+	if ( pwdinfo->persistent_supported )
+	{
+		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
+	}
+	else
+	{
+		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
+	}
+
+	//	Group Owner Intent
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
+	p2pielen += 2;
+
+	//	Value:
+	if ( pwdinfo->peer_intent & 0x01 )
+	{
+		//	Peer's tie breaker bit is 1, our tie breaker bit should be 0
+		p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
+	}
+	else
+	{
+		//	Peer's tie breaker bit is 0, our tie breaker bit should be 1
+		p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
+	}
+
+
+	//	Configuration Timeout
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
+	p2pielen += 2;
+
+	//	Value:
+	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
+	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
+
+	//	Operating Channel
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
+	p2pielen += 2;
+
+	//	Value:
+	//	Country String
+	p2pie[ p2pielen++ ] = 'X';
+	p2pie[ p2pielen++ ] = 'X';
+	
+	//	The third byte should be set to 0x04.
+	//	Described in the "Operating Channel Attribute" section.
+	p2pie[ p2pielen++ ] = 0x04;
+
+	//	Operating Class
+	if ( pwdinfo->operating_channel <= 14 )
+	{
+		//	Operating Class
+		p2pie[ p2pielen++ ] = 0x51;
+	}
+	else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
+	{
+		//	Operating Class
+		p2pie[ p2pielen++ ] = 0x73;
+	}
+	else
+	{
+		//	Operating Class
+		p2pie[ p2pielen++ ] = 0x7c;
+	}
+	
+	//	Channel Number
+	p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
+
+	//	Intended P2P Interface Address	
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
+	p2pielen += 2;
+
+	//	Value:
+	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
+	p2pielen += ETH_ALEN;
+
+	//	Channel List
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
+
+	// Country String(3)
+	// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
+	// + number of channels in all classes
+	len_channellist_attr = 3
+	   + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
+	   + get_reg_classes_full_count(pmlmeext->channel_list);
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
+	{
+		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
+	}
+	else
+	{
+		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
+	}
+#else
+
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
+
+ #endif
+	p2pielen += 2;
+
+	//	Value:
+	//	Country String
+	p2pie[ p2pielen++ ] = 'X';
+	p2pie[ p2pielen++ ] = 'X';
+	
+	//	The third byte should be set to 0x04.
+	//	Described in the "Operating Channel Attribute" section.
+	p2pie[ p2pielen++ ] = 0x04;
+
+	//	Channel Entry List
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
+	{
+		_adapter *pbuddy_adapter = padapter->pbuddy_adapter;	
+		struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+
+		//	Operating Class
+		if ( pbuddy_mlmeext->cur_channel > 14 )
+		{
+			if ( pbuddy_mlmeext->cur_channel >= 149 )
+			{
+				p2pie[ p2pielen++ ] = 0x7c;
+			}
+			else
+			{
+				p2pie[ p2pielen++ ] = 0x73;
+			}
+		}
+		else
+		{
+			p2pie[ p2pielen++ ] = 0x51;
+		}
+
+		//	Number of Channels
+		//	Just support 1 channel and this channel is AP's channel
+		p2pie[ p2pielen++ ] = 1;
+
+		//	Channel List
+		p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
+	}
+	else
+	{
+		int i, j;
+		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
+			//	Operating Class
+			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
+
+			//	Number of Channels
+			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
+
+			//	Channel List
+			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
+				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
+			}
+		}
+	}
+#else // CONFIG_CONCURRENT_MODE
+	{
+		int i, j;
+		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
+			//	Operating Class
+			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
+
+			//	Number of Channels
+			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
+
+			//	Channel List
+			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
+				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
+			}
+		}
+	}
+#endif // CONFIG_CONCURRENT_MODE
+
+	
+	//	Device Info
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
+
+	//	Length:
+	//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
+	//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
+	p2pielen += 2;
+
+	//	Value:
+	//	P2P Device Address
+	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
+	p2pielen += ETH_ALEN;
+
+	//	Config Method
+	//	This field should be big endian. Noted by P2P specification.
+
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
+
+	p2pielen += 2;
+
+	//	Primary Device Type
+	//	Category ID
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
+	p2pielen += 2;
+
+	//	OUI
+	*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
+	p2pielen += 4;
+
+	//	Sub Category ID
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
+	p2pielen += 2;
+
+	//	Number of Secondary Device Types
+	p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
+
+	//	Device Name
+	//	Type:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
+	p2pielen += 2;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
+	p2pielen += 2;
+
+	//	Value:
+	_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
+	p2pielen += pwdinfo->device_name_len;	
+	
+	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
+	{
+		//	Group ID Attribute
+		//	Type:
+		p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
+
+		//	Length:
+		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
+		p2pielen += 2;
+
+		//	Value:
+		//	p2P Device Address
+		_rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
+		p2pielen += ETH_ALEN;
+
+		//	SSID
+		_rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
+		p2pielen += pwdinfo->nego_ssidlen;
+		
+	}
+	
+	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen );	
+	
+#ifdef CONFIG_WFD
+	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
+	pframe += wfdielen;
+	pktlen += wfdielen;
+#endif
+	
+	*pLength = pktlen;
+#if 0
+	// printf dbg msg
+	dbgbufLen = pktlen;
+	DBG_871X("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
+
+	for(index=0;index<dbgbufLen;index++)
+		printk("%x ",*(dbgbuf+index));
+	
+	printk("\n");
+	DBG_871X("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
+#endif
+}
+
+static void rtw_hal_construct_P2PInviteRsp(_adapter * padapter, u8 * pframe, u32 * pLength)
+{
+	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
+	u8			action = P2P_PUB_ACTION_ACTION;
+	u32			p2poui = cpu_to_be32(P2POUI);
+	u8			oui_subtype = P2P_INVIT_RESP;
+	u8			p2pie[ 255 ] = { 0x00 };
+	u8			p2pielen = 0, i;
+	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
+	u16			len_channellist_attr = 0;
+	u32			pktlen;
+	u8			dialogToken = 0;
+#ifdef CONFIG_CONCURRENT_MODE
+	_adapter				*pbuddy_adapter = padapter->pbuddy_adapter;
+	struct wifidirect_info	*pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
+	struct mlme_priv		*pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
+	struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+#endif	
+#ifdef CONFIG_WFD
+	u32					wfdielen = 0;
+#endif
+	
+	//struct xmit_frame			*pmgntframe;
+	//struct pkt_attrib			*pattrib;
+	//unsigned char					*pframe;
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	unsigned short				*fctrl;
+	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
+
+	//for debug
+	u8 *dbgbuf = pframe;
+	u8 dbgbufLen = 0, index = 0;
+
+
+	DBG_871X( "%s\n", __FUNCTION__);
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+
+	//RA fill by FW
+	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+
+	//BSSID fill by FW
+	_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0);
+	SetFrameSubType(pframe, WIFI_ACTION);
+
+	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));	
+
+	//dialog token, filled by FW
+	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
+
+	//	P2P IE Section.
+
+	//	P2P OUI
+	p2pielen = 0;
+	p2pie[ p2pielen++ ] = 0x50;
+	p2pie[ p2pielen++ ] = 0x6F;
+	p2pie[ p2pielen++ ] = 0x9A;
+	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
+
+	//	Commented by Albert 20101005
+	//	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
+	//	1. Status
+	//	2. Configuration Timeout
+	//	3. Operating Channel	( Only GO )
+	//	4. P2P Group BSSID	( Only GO )
+	//	5. Channel List
+
+	//	P2P Status
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
+	p2pielen += 2;
+
+	//	Value: filled by FW, defult value is FAIL INFO UNAVAILABLE
+	p2pie[ p2pielen++ ] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
+	
+	//	Configuration Timeout
+	//	Type:
+	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
+
+	//	Length:
+	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
+	p2pielen += 2;
+
+	//	Value:
+	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
+	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
+
+	// due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed
+#if 0 
+	if( status_code == P2P_STATUS_SUCCESS )
+	{
+		if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
+		{
+			//	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
+			//	In this case, the P2P Invitation response frame should carry the two more P2P attributes.
+			//	First one is operating channel attribute.
+			//	Second one is P2P Group BSSID attribute.
+
+			//	Operating Channel
+			//	Type:
+			p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
+
+			//	Length:
+			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
+			p2pielen += 2;
+
+			//	Value:
+			//	Country String
+			p2pie[ p2pielen++ ] = 'X';
+			p2pie[ p2pielen++ ] = 'X';
+		
+			//	The third byte should be set to 0x04.
+			//	Described in the "Operating Channel Attribute" section.
+			p2pie[ p2pielen++ ] = 0x04;
+
+			//	Operating Class
+			p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
+		
+			//	Channel Number
+			p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
+			
+
+			//	P2P Group BSSID
+			//	Type:
+			p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
+
+			//	Length:
+			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
+			p2pielen += 2;
+
+			//	Value:
+			//	P2P Device Address for GO
+			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
+			p2pielen += ETH_ALEN;
+
+		}
+
+		//	Channel List
+		//	Type:
+		p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
+
+		//	Length:
+		// Country String(3)
+		// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
+		// + number of channels in all classes
+		len_channellist_attr = 3
+			+ (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
+			+ get_reg_classes_full_count(pmlmeext->channel_list);
+
+#ifdef CONFIG_CONCURRENT_MODE
+		if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
+		{
+			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
+		}
+		else
+		{
+			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
+		}
+#else
+
+		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
+
+#endif
+		p2pielen += 2;
+
+		//	Value:
+		//	Country String
+		p2pie[ p2pielen++ ] = 'X';
+		p2pie[ p2pielen++ ] = 'X';
+
+		//	The third byte should be set to 0x04.
+		//	Described in the "Operating Channel Attribute" section.
+		p2pie[ p2pielen++ ] = 0x04;
+
+		//	Channel Entry List
+#ifdef CONFIG_CONCURRENT_MODE
+		if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
+		{
+			_adapter *pbuddy_adapter = padapter->pbuddy_adapter;	
+			struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+
+			//	Operating Class
+			if ( pbuddy_mlmeext->cur_channel > 14 )
+			{
+				if ( pbuddy_mlmeext->cur_channel >= 149 )
+				{
+					p2pie[ p2pielen++ ] = 0x7c;
+				}
+				else
+				{
+					p2pie[ p2pielen++ ] = 0x73;
+				}
+			}
+			else
+			{
+				p2pie[ p2pielen++ ] = 0x51;
+			}
+
+			//	Number of Channels
+			//	Just support 1 channel and this channel is AP's channel
+			p2pie[ p2pielen++ ] = 1;
+
+			//	Channel List
+			p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
+		}
+		else
+		{
+			int i, j;
+			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
+				//	Operating Class
+				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
+
+				//	Number of Channels
+				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
+
+				//	Channel List
+				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
+					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
+				}
+			}
+		}
+#else // CONFIG_CONCURRENT_MODE
+		{
+			int i, j;
+			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
+				//	Operating Class
+				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
+
+				//	Number of Channels
+				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
+
+				//	Channel List
+				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
+					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
+				}
+			}
+		}
+#endif // CONFIG_CONCURRENT_MODE
+	}
+#endif
+
+	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen );	
+	
+#ifdef CONFIG_WFD
+	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
+	pframe += wfdielen;
+	pktlen += wfdielen;
+#endif
+
+	*pLength = pktlen;
+
+#if 0
+	// printf dbg msg
+	dbgbufLen = pktlen;
+	DBG_871X("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
+
+	for(index=0;index<dbgbufLen;index++)
+		printk("%x ",*(dbgbuf+index));
+	
+	printk("\n");
+	DBG_871X("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
+#endif
+}
+
+
+static void rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter, u8 * pframe, u32 * pLength)
+{
+	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
+	u8			action = P2P_PUB_ACTION_ACTION;
+	u8			dialogToken = 0;	
+	u32			p2poui = cpu_to_be32(P2POUI);
+	u8			oui_subtype = P2P_PROVISION_DISC_RESP;
+	u8			wpsie[ 100 ] = { 0x00 };
+	u8			wpsielen = 0;
+	u32			pktlen;
+#ifdef CONFIG_WFD
+	u32					wfdielen = 0;
+#endif
+	
+	//struct xmit_frame			*pmgntframe;
+	//struct pkt_attrib			*pattrib;
+	//unsigned char					*pframe;
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	unsigned short				*fctrl;
+	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
+
+	//for debug
+	u8 *dbgbuf = pframe;
+	u8 dbgbufLen = 0, index = 0;
+
+	DBG_871X( "%s\n", __FUNCTION__);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+
+	//RA filled by FW
+	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+
+	SetSeqNum(pwlanhdr,0);
+	SetFrameSubType(pframe, WIFI_ACTION);
+
+	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
+	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));	
+	//dialog token, filled by FW
+	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));		
+
+	wpsielen = 0;
+	//	WPS OUI
+	//*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
+	RTW_PUT_BE32(wpsie, WPSOUI);
+	wpsielen += 4;
+
+#if 0
+	//	WPS version
+	//	Type:
+	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
+	wpsielen += 2;
+
+	//	Length:
+	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
+	wpsielen += 2;
+
+	//	Value:
+	wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
+#endif
+
+	//	Config Method
+	//	Type:
+	//*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
+	RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
+	wpsielen += 2;
+
+	//	Length:
+	//*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
+	RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
+	wpsielen += 2;
+
+	//	Value: filled by FW, default value is PBC
+	//*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method );
+	RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
+	wpsielen += 2;
+
+	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen );	
+
+#ifdef CONFIG_WFD
+	wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
+	pframe += wfdielen;
+	pktlen += wfdielen;
+#endif
+
+	*pLength = pktlen;
+
+	// printf dbg msg
+#if 0
+	dbgbufLen = pktlen;
+	DBG_871X("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
+
+	for(index=0;index<dbgbufLen;index++)
+		printk("%x ",*(dbgbuf+index));
+
+	printk("\n");
+	DBG_871X("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
+#endif
+}
+
+u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter* adapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+	u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN]={0};
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	u8 ret = _FAIL;
+
+	DBG_871X("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",  
+		rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
+		rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
+		rsvdpageloc->LocPDRsp);
+
+	SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
+	SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
+	SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
+	SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
+	SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
+	
+	//FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm);
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_P2P_OFFLOAD_RSVD_PAGE,
+				H2C_P2PRSVDPAGE_LOC_LEN,
+				u1H2CP2PRsvdPageParm);
+
+	return ret;
+}
+
+u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter* adapter)
+{
+
+	u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
+	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
+	struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	u8 ret = _FAIL;
+
+	_rtw_memset(p2p_wowlan_offload,0 ,sizeof(struct P2P_WoWlan_Offload_t)); 
+	DBG_871X("%s\n",__func__);	
+	switch(pwdinfo->role)
+	{
+		case P2P_ROLE_DEVICE:
+			DBG_871X("P2P_ROLE_DEVICE\n");
+			p2p_wowlan_offload->role = 0;
+			break;
+		case P2P_ROLE_CLIENT:
+			DBG_871X("P2P_ROLE_CLIENT\n");
+			p2p_wowlan_offload->role = 1;
+			break;
+		case P2P_ROLE_GO:
+			DBG_871X("P2P_ROLE_GO\n");
+			p2p_wowlan_offload->role = 2;
+			break;
+		default: 
+			DBG_871X("P2P_ROLE_DISABLE\n");
+			break;
+		}
+	p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm>>8;
+	p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
+	offload_cmd = (u8*)p2p_wowlan_offload;
+	DBG_871X("p2p_wowlan_offload: %x:%x:%x\n",offload_cmd[0],offload_cmd[1],offload_cmd[2]);	
+
+	ret = rtw_hal_fill_h2c_cmd(adapter,
+				H2C_P2P_OFFLOAD,
+				H2C_P2P_OFFLOAD_LEN,
+				offload_cmd);
+	return ret;
+
+	//FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload);
+}
+#endif //CONFIG_P2P_WOWLAN
+
+static void rtw_hal_construct_beacon(_adapter *padapter,
+		u8 *pframe, u32 *pLength)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16					*fctrl;
+	u32					rate_len, pktlen;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
+	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+
+	//DBG_871X("%s\n", __FUNCTION__);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+
+	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
+	//pmlmeext->mgnt_seq++;
+	SetFrameSubType(pframe, WIFI_BEACON);
+
+	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+	pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
+
+	//timestamp will be inserted by hardware
+	pframe += 8;
+	pktlen += 8;
+
+	// beacon interval: 2 bytes
+	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
+
+	pframe += 2;
+	pktlen += 2;
+
+	// capability info: 2 bytes
+	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
+
+	pframe += 2;
+	pktlen += 2;
+
+	if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
+	{
+		//DBG_871X("ie len=%d\n", cur_network->IELength);
+		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
+		_rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);
+
+		goto _ConstructBeacon;
+	}
+
+	//below for ad-hoc mode
+
+	// SSID
+	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
+
+	// supported rates...
+	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
+	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
+
+	// DS parameter set
+	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
+
+	if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
+	{
+		u32 ATIMWindow;
+		// IBSS Parameter Set...
+		//ATIMWindow = cur->Configuration.ATIMWindow;
+		ATIMWindow = 0;
+		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
+	}
+
+
+	//todo: ERP IE
+
+
+	// EXTERNDED SUPPORTED RATE
+	if (rate_len > 8)
+	{
+		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
+	}
+
+
+	//todo:HT for adhoc
+
+_ConstructBeacon:
+
+	if ((pktlen + TXDESC_SIZE) > 512)
+	{
+		DBG_871X("beacon frame too large\n");
+		return;
+	}
+
+	*pLength = pktlen;
+
+	//DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen);
+
+}
+
+static void rtw_hal_construct_PSPoll(_adapter *padapter,
+		u8 *pframe, u32 *pLength)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16					*fctrl;
+	u32					pktlen;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+
+	//DBG_871X("%s\n", __FUNCTION__);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+	// Frame control.
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+	SetPwrMgt(fctrl);
+	SetFrameSubType(pframe, WIFI_PSPOLL);
+
+	// AID.
+	SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
+
+	// BSSID.
+	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+	// TA.
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+
+	*pLength = 16;
+}
+
+static void rtw_hal_construct_NullFunctionData(
+	PADAPTER padapter,
+	u8		*pframe,
+	u32		*pLength,
+	u8		*StaAddr,
+	u8		bQoS,
+	u8		AC,
+	u8		bEosp,
+	u8		bForcePowerSave)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16						*fctrl;
+	u32						pktlen;
+	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
+	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+
+
+	//DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
+
+	fctrl = &pwlanhdr->frame_ctl;
+	*(fctrl) = 0;
+	if (bForcePowerSave)
+	{
+		SetPwrMgt(fctrl);
+	}
+
+	switch(cur_network->network.InfrastructureMode)
+	{
+		case Ndis802_11Infrastructure:
+			SetToDs(fctrl);
+			_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
+			break;
+		case Ndis802_11APMode:
+			SetFrDs(fctrl);
+			_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+			break;
+		case Ndis802_11IBSS:
+		default:
+			_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+			break;
+	}
+
+	SetSeqNum(pwlanhdr, 0);
+
+	if (bQoS == _TRUE) {
+		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
+
+		SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
+
+		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
+		SetPriority(&pwlanqoshdr->qc, AC);
+		SetEOSP(&pwlanqoshdr->qc, bEosp);
+
+		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
+	} else {
+		SetFrameSubType(pframe, WIFI_DATA_NULL);
+
+		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+	}
+
+	*pLength = pktlen;
+}
+
+void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
+		u8 *StaAddr, BOOLEAN bHideSSID)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16					*fctrl;
+	u8					*mac, *bssid;
+	u32					pktlen;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	WLAN_BSSID_EX  *cur_network = &(pmlmeinfo->network);
+
+	/*DBG_871X("%s\n", __FUNCTION__);*/
+
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+	mac = adapter_mac_addr(padapter);
+	bssid = cur_network->MacAddress;
+
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+	_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0);
+	SetFrameSubType(fctrl, WIFI_PROBERSP);
+
+	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+	pframe += pktlen;
+
+	if (cur_network->IELength > MAX_IE_SZ)
+		return;
+
+	_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
+	pframe += cur_network->IELength;
+	pktlen += cur_network->IELength;
+
+	*pLength = pktlen;
+}
+
+#ifdef CONFIG_WOWLAN	
+//
+// Description:
+//	Construct the ARP response packet to support ARP offload.
+//
+static void rtw_hal_construct_ARPRsp(
+	PADAPTER padapter,
+	u8			*pframe,
+	u32			*pLength,
+	u8			*pIPAddress
+	)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16	*fctrl;
+	u32	pktlen;
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct security_priv	*psecuritypriv = &padapter->securitypriv;
+	static u8	ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
+	u8	*pARPRspPkt = pframe;
+	//for TKIP Cal MIC
+	u8	*payload = pframe;
+	u8	EncryptionHeadOverhead = 0;
+	//DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
+
+	fctrl = &pwlanhdr->frame_ctl;
+	*(fctrl) = 0;
+
+	//-------------------------------------------------------------------------
+	// MAC Header.
+	//-------------------------------------------------------------------------
+	SetFrameType(fctrl, WIFI_DATA);
+	//SetFrameSubType(fctrl, 0);
+	SetToDs(fctrl);
+	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0);
+	SetDuration(pwlanhdr, 0);
+	//SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0);
+	//SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data);
+	//SET_80211_HDR_TO_DS(pARPRspPkt, 1);
+	//SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid);
+	//SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress);
+	//SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid);
+
+	//SET_80211_HDR_DURATION(pARPRspPkt, 0);
+	//SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0);
+#ifdef CONFIG_WAPI_SUPPORT
+	*pLength = sMacHdrLng;
+#else
+	*pLength = 24;
+#endif
+	switch (psecuritypriv->dot11PrivacyAlgrthm) {
+		case _WEP40_:
+		case _WEP104_:
+			EncryptionHeadOverhead = 4;
+			break;
+		case _TKIP_:
+			EncryptionHeadOverhead = 8;
+			break;
+		case _AES_:
+			EncryptionHeadOverhead = 8;
+			break;
+#ifdef CONFIG_WAPI_SUPPORT
+		case _SMS4_:
+			EncryptionHeadOverhead = 18;
+			break;
+#endif
+		default:
+			EncryptionHeadOverhead = 0;
+	}
+
+	if(EncryptionHeadOverhead > 0) {
+		_rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
+		*pLength += EncryptionHeadOverhead;
+		//SET_80211_HDR_WEP(pARPRspPkt, 1);  //Suggested by CCW.
+		SetPrivacy(fctrl);
+	}
+
+	//-------------------------------------------------------------------------
+	// Frame Body.
+	//-------------------------------------------------------------------------
+	pARPRspPkt =  (u8*)(pframe+ *pLength);
+	payload = pARPRspPkt; //Get Payload pointer
+	// LLC header
+	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
+	*pLength += 8;
+
+	// ARP element
+	pARPRspPkt += 8;
+	SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
+	SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008);	// IP protocol
+	SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
+	SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
+	SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200);	// ARP response
+	SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
+	SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
+#ifdef CONFIG_ARP_KEEP_ALIVE
+	if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
+		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
+		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
+	}    
+	else
+#endif
+	{
+		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt,
+				get_my_bssid(&(pmlmeinfo->network)));
+		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt,
+				pIPAddress);
+		DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
+				MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
+		DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
+				IP_ARG(pIPAddress));
+	}
+
+	*pLength += 28;
+
+	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
+		u8	mic[8];
+		struct mic_data	micdata;
+		struct sta_info	*psta = NULL;
+		u8	priority[4]={0x0,0x0,0x0,0x0};
+		u8	null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
+
+		DBG_871X("%s(): Add MIC\n",__FUNCTION__);
+
+		psta = rtw_get_stainfo(&padapter->stapriv,
+				get_my_bssid(&(pmlmeinfo->network)));
+		if (psta != NULL) {
+			if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
+						null_key, 16)==_TRUE) {
+				DBG_871X("%s(): STA dot11tkiptxmickey==0\n",
+						__func__);
+			}
+			//start to calculate the mic code
+			rtw_secmicsetkey(&micdata,
+					&psta->dot11tkiptxmickey.skey[0]);
+		}
+
+		rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  //DA
+
+		rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA
+
+		priority[0]=0;
+
+		rtw_secmicappend(&micdata, &priority[0], 4);
+
+		rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28
+
+		rtw_secgetmic(&micdata,&(mic[0]));
+
+		pARPRspPkt += 28;
+		_rtw_memcpy(pARPRspPkt, &(mic[0]),8);
+
+		*pLength += 8;
+	}
+}
+
+#ifdef CONFIG_PNO_SUPPORT
+static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
+		u32 *pLength, pno_ssid_t *ssid)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16				*fctrl;
+	u32				pktlen;
+	unsigned char			*mac;
+	unsigned char			bssrate[NumRates];
+	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
+	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	int	bssrate_len = 0;
+	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+	mac = adapter_mac_addr(padapter);
+
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+
+	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
+
+	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0);
+	SetFrameSubType(pframe, WIFI_PROBEREQ);
+
+	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+	pframe += pktlen;
+
+	if (ssid == NULL) {
+		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
+	} else {
+		//DBG_871X("%s len:%d\n", ssid->SSID, ssid->SSID_len);
+		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
+	}
+
+	get_rate_set(padapter, bssrate, &bssrate_len);
+
+	if (bssrate_len > 8)
+	{
+		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
+		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
+	}
+	else
+	{
+		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
+	}
+
+	*pLength = pktlen;
+}
+
+static void rtw_hal_construct_PNO_info(_adapter *padapter,
+		u8 *pframe, u32*pLength)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+
+	u8	*pPnoInfoPkt = pframe;
+	pPnoInfoPkt =  (u8*)(pframe+ *pLength);
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
+
+	*pLength+=1;
+	pPnoInfoPkt += 1;
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
+
+	*pLength+=3;
+	pPnoInfoPkt += 3;
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
+
+	*pLength+=4;
+	pPnoInfoPkt += 4;
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
+
+	*pLength+=4;
+	pPnoInfoPkt += 4;
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
+
+	*pLength+=4;
+	pPnoInfoPkt += 4;
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length,
+			MAX_PNO_LIST_COUNT);
+
+	*pLength+=MAX_PNO_LIST_COUNT;
+	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info,
+			MAX_PNO_LIST_COUNT);
+
+	*pLength+=MAX_PNO_LIST_COUNT;
+	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info,
+			MAX_PNO_LIST_COUNT);
+
+	*pLength+=MAX_PNO_LIST_COUNT;
+	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
+	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req,
+			MAX_HIDDEN_AP);
+
+	*pLength+=MAX_HIDDEN_AP;
+	pPnoInfoPkt += MAX_HIDDEN_AP;
+}
+
+static void rtw_hal_construct_ssid_list(_adapter *padapter,
+	u8 *pframe, u32 *pLength)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+	u8 *pSSIDListPkt = pframe;
+	int i;
+
+	pSSIDListPkt =  (u8*)(pframe+ *pLength);
+
+	for(i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
+		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
+			pwrctl->pnlo_info->ssid_length[i]);
+
+		*pLength += WLAN_SSID_MAXLEN;
+		pSSIDListPkt += WLAN_SSID_MAXLEN;
+	}
+}
+
+static void rtw_hal_construct_scan_info(_adapter *padapter,
+	u8 *pframe, u32 *pLength)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+	u8 *pScanInfoPkt = pframe;
+	int i;
+
+	pScanInfoPkt =  (u8*)(pframe+ *pLength);
+
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
+
+	*pLength+=1;
+	pScanInfoPkt += 1;
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
+
+
+	*pLength+=1;
+	pScanInfoPkt += 1;
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
+
+
+	*pLength+=1;
+	pScanInfoPkt += 1;
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
+
+	*pLength+=1;
+	pScanInfoPkt += 1;
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
+
+	*pLength+=1;
+	pScanInfoPkt += 1;
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
+
+	*pLength+=1;
+	pScanInfoPkt += 1;
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
+
+	*pLength+=1;
+	pScanInfoPkt += 1;
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
+
+	*pLength+=1;
+	pScanInfoPkt += 1;
+	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
+
+	*pLength+=8;
+	pScanInfoPkt += 8;
+
+	for(i = 0 ; i < MAX_SCAN_LIST_COUNT ; i ++) {
+		_rtw_memcpy(pScanInfoPkt,
+			&pwrctl->pscan_info->ssid_channel_info[i], 4);
+		*pLength+=4;
+		pScanInfoPkt += 4;
+	}
+}
+#endif //CONFIG_PNO_SUPPORT
+
+#ifdef CONFIG_GTK_OL
+static void rtw_hal_construct_GTKRsp(
+	PADAPTER	padapter,
+	u8		*pframe,
+	u32		*pLength
+	)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16	*fctrl;
+	u32	pktlen;
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct security_priv	*psecuritypriv = &padapter->securitypriv;
+	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
+	static u8	GTKbody_a[11] ={0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
+	u8	*pGTKRspPkt = pframe;
+	u8	EncryptionHeadOverhead = 0;
+	//DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
+
+	fctrl = &pwlanhdr->frame_ctl;
+	*(fctrl) = 0;
+
+	//-------------------------------------------------------------------------
+	// MAC Header.
+	//-------------------------------------------------------------------------
+	SetFrameType(fctrl, WIFI_DATA);
+	//SetFrameSubType(fctrl, 0);
+	SetToDs(fctrl);
+
+	_rtw_memcpy(pwlanhdr->addr1,
+			get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+	_rtw_memcpy(pwlanhdr->addr2,
+			adapter_mac_addr(padapter), ETH_ALEN);
+
+	_rtw_memcpy(pwlanhdr->addr3,
+			get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0);
+	SetDuration(pwlanhdr, 0);
+
+#ifdef CONFIG_WAPI_SUPPORT
+	*pLength = sMacHdrLng;
+#else
+	*pLength = 24;
+#endif //CONFIG_WAPI_SUPPORT
+
+	//-------------------------------------------------------------------------
+	// Security Header: leave space for it if necessary.
+	//-------------------------------------------------------------------------
+	switch (psecuritypriv->dot11PrivacyAlgrthm) {
+		case _WEP40_:
+		case _WEP104_:
+			EncryptionHeadOverhead = 4;
+			break;
+		case _TKIP_:
+			EncryptionHeadOverhead = 8;
+			break;
+		case _AES_:
+			EncryptionHeadOverhead = 8;
+			break;
+#ifdef CONFIG_WAPI_SUPPORT
+		case _SMS4_:
+			EncryptionHeadOverhead = 18;
+			break;
+#endif //CONFIG_WAPI_SUPPORT
+		default:
+			EncryptionHeadOverhead = 0;
+	}
+
+	if (EncryptionHeadOverhead > 0) {
+		_rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
+		*pLength += EncryptionHeadOverhead;
+		//SET_80211_HDR_WEP(pGTKRspPkt, 1);  //Suggested by CCW.
+		//GTK's privacy bit is done by FW
+		//SetPrivacy(fctrl);
+	}
+	//-------------------------------------------------------------------------
+	// Frame Body.
+	//-------------------------------------------------------------------------
+	pGTKRspPkt =  (u8*)(pframe+ *pLength);
+	// LLC header
+	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
+	*pLength += 8;
+
+	// GTK element
+	pGTKRspPkt += 8;
+
+	//GTK frame body after LLC, part 1
+	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
+	*pLength += 11;
+	pGTKRspPkt += 11;
+	//GTK frame body after LLC, part 2
+	_rtw_memset(&(pframe[*pLength]), 0, 88);
+	*pLength += 88;
+	pGTKRspPkt += 88;
+
+}
+#endif //CONFIG_GTK_OL
+
+void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
+		u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
+		RSVDPAGE_LOC *rsvd_page_loc)
+{
+	struct security_priv *psecuritypriv = &adapter->securitypriv;
+	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+	struct mlme_ext_priv	*pmlmeext;
+	struct mlme_ext_info	*pmlmeinfo;
+	u32	ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0;
+	u32	SSIDLegnth = 0, ProbeReqLength = 0;
+	u8 CurtPktPageNum = 0;
+	u8 currentip[4];
+	u8 cur_dot11txpn[8];
+
+#ifdef CONFIG_GTK_OL
+	struct sta_priv *pstapriv = &adapter->stapriv;
+	struct sta_info * psta;
+	u8 kek[RTW_KEK_LEN];
+	u8 kck[RTW_KCK_LEN];
+#endif //CONFIG_GTK_OL
+#ifdef	CONFIG_PNO_SUPPORT 
+	int pno_index;
+	u8 ssid_num;
+#endif //CONFIG_PNO_SUPPORT
+
+	pmlmeext = &adapter->mlmeextpriv;
+	pmlmeinfo = &pmlmeext->mlmext_info;
+
+	if (pwrctl->wowlan_pno_enable == _FALSE) {
+		//ARP RSP * 1 page
+		rtw_get_current_ip_address(adapter, currentip);
+
+		rsvd_page_loc->LocArpRsp = *page_num;
+
+		rtw_hal_construct_ARPRsp( adapter, &pframe[index],
+				&ARPLegnth, currentip);
+
+		rtw_hal_fill_fake_txdesc(adapter,
+				&pframe[index-tx_desc],
+				ARPLegnth, _FALSE, _FALSE, _TRUE);
+
+		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLegnth, page_size);
+
+		*page_num += CurtPktPageNum;
+
+		index += (CurtPktPageNum * page_size);
+
+		//3 SEC IV * 1 page
+		rtw_get_sec_iv(adapter, cur_dot11txpn,
+				get_my_bssid(&pmlmeinfo->network));
+
+		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
+
+		_rtw_memcpy(pframe+index-tx_desc, cur_dot11txpn, _AES_IV_LEN_);
+
+		CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, page_size);
+
+		*page_num += CurtPktPageNum;
+
+		*total_pkt_len = index + _AES_IV_LEN_;
+#ifdef CONFIG_GTK_OL
+		index += (CurtPktPageNum * page_size);
+
+		//if the ap staion info. exists, get the kek, kck from staion info.
+		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+		if (psta == NULL) {
+			_rtw_memset(kek, 0, RTW_KEK_LEN);
+			_rtw_memset(kck, 0, RTW_KCK_LEN);
+			DBG_8192C("%s, KEK, KCK download rsvd page all zero \n",
+					__func__);
+		} else {
+			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
+			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
+		}
+
+		//3 KEK, KCK
+		rsvd_page_loc->LocGTKInfo = *page_num;
+		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
+			struct security_priv *psecpriv = NULL;
+			
+			psecpriv = &adapter->securitypriv;
+			_rtw_memcpy(pframe+index-tx_desc,
+					&psecpriv->dot11PrivacyAlgrthm, 1);
+			_rtw_memcpy(pframe+index-tx_desc+1,
+					&psecpriv->dot118021XGrpPrivacy, 1);
+			_rtw_memcpy(pframe+index-tx_desc+2,
+					kck, RTW_KCK_LEN);
+			_rtw_memcpy(pframe+index-tx_desc+2+RTW_KCK_LEN,
+					kek, RTW_KEK_LEN);
+			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
+		} else {
+			_rtw_memcpy(pframe+index-tx_desc, kck, RTW_KCK_LEN);
+			_rtw_memcpy(pframe+index-tx_desc+RTW_KCK_LEN, kek, RTW_KEK_LEN);
+			CurtPktPageNum = (u8)PageNum(tx_desc + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
+		}
+		
+		
+
+#if 0
+		{
+			int i;
+			printk("\ntoFW KCK: ");
+			for(i=0;i<16; i++)
+				printk(" %02x ", kck[i]);
+			printk("\ntoFW KEK: ");
+			for(i=0;i<16; i++)
+				printk(" %02x ", kek[i]);
+			printk("\n");
+		}
+
+		DBG_871X("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n", 
+			__FUNCTION__, &pframe[index-tx_desc],
+			(tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
+#endif
+
+		*page_num += CurtPktPageNum;
+
+		index += (CurtPktPageNum * page_size);
+
+		//3 GTK Response
+		rsvd_page_loc->LocGTKRsp= *page_num;
+		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLegnth);
+
+		rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc],
+				GTKLegnth, _FALSE, _FALSE, _TRUE);
+#if 0
+		{
+			int gj;
+			printk("123GTK pkt=> \n");
+			for(gj=0; gj < GTKLegnth+tx_desc; gj++) {
+				printk(" %02x ", pframe[index-tx_desc+gj]);
+				if ((gj + 1)%16==0)
+					printk("\n");
+			}
+			printk(" <=end\n");
+		}
+
+		DBG_871X("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
+			__FUNCTION__, &pframe[index-tx_desc],
+			(tx_desc + GTKLegnth));
+#endif
+
+		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLegnth, page_size);
+
+		*page_num += CurtPktPageNum;
+
+		index += (CurtPktPageNum * page_size);
+
+		//below page is empty for GTK extension memory
+		//3(11) GTK EXT MEM
+		rsvd_page_loc->LocGTKEXTMEM = *page_num;
+
+		CurtPktPageNum = 2;
+
+		*page_num += CurtPktPageNum;
+		//extension memory for FW
+		*total_pkt_len =
+			index - tx_desc + (page_size * CurtPktPageNum);
+#endif //CONFIG_GTK_OL
+	} else {
+#ifdef CONFIG_PNO_SUPPORT
+		if (pwrctl->pno_in_resume == _FALSE &&
+				pwrctl->pno_inited == _TRUE) {
+
+			//Broadcast Probe Request
+			rsvd_page_loc->LocProbePacket = *page_num;
+
+			DBG_871X("loc_probe_req: %d\n",
+					rsvd_page_loc->LocProbePacket);
+
+			rtw_hal_construct_ProbeReq(
+				adapter,
+				&pframe[index],
+				&ProbeReqLength,
+				NULL);
+
+			rtw_hal_fill_fake_txdesc(adapter,
+				&pframe[index-tx_desc],
+				ProbeReqLength, _FALSE, _FALSE, _FALSE);
+
+			CurtPktPageNum =
+				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
+
+			*page_num += CurtPktPageNum;
+
+			index += (CurtPktPageNum * page_size);
+
+			//Hidden SSID Probe Request
+			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
+
+			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
+				pwrctl->pnlo_info->loc_probe_req[pno_index] =
+					*page_num;
+
+				rtw_hal_construct_ProbeReq(
+					adapter,
+					&pframe[index],
+					&ProbeReqLength,
+					&pwrctl->pno_ssid_list->node[pno_index]);
+
+				rtw_hal_fill_fake_txdesc(adapter,
+					&pframe[index - tx_desc],
+					ProbeReqLength, _FALSE, _FALSE, _FALSE);
+
+				CurtPktPageNum =
+					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
+
+				*page_num += CurtPktPageNum;
+
+				index += (CurtPktPageNum * page_size);
+			}
+
+			//PNO INFO Page
+			rsvd_page_loc->LocPNOInfo = *page_num;
+			rtw_hal_construct_PNO_info(adapter,
+					&pframe[index - tx_desc],
+					&PNOLength);
+
+			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
+			*page_num += CurtPktPageNum;
+			index += (CurtPktPageNum * page_size);
+
+			//SSID List Page
+			rsvd_page_loc->LocSSIDInfo = *page_num;
+			rtw_hal_construct_ssid_list(adapter,
+					&pframe[index - tx_desc],
+					&SSIDLegnth);
+
+			CurtPktPageNum = (u8)PageNum(SSIDLegnth, page_size);
+			*page_num += CurtPktPageNum;
+			index += (CurtPktPageNum * page_size);
+
+			//Scan Info Page
+			rsvd_page_loc->LocScanInfo = *page_num;
+			rtw_hal_construct_scan_info(adapter,
+					&pframe[index - tx_desc],
+					&ScanInfoLength);
+
+			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
+			*page_num += CurtPktPageNum;
+			index += (CurtPktPageNum * page_size);
+			*total_pkt_len = index + ScanInfoLength;
+		}
+#endif //CONFIG_PNO_SUPPORT
+	}
+}
+
+static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
+{
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+	u8 val8 = 0;
+	u16 val16 = 0;
+
+	if (stop) {
+		/* Pause TX*/
+		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
+		rtw_write8(adapter, REG_TXPAUSE, 0xff);
+		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
+		val8 &= ~BIT(0);
+		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
+		DBG_871X("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
+				__func__,
+				rtw_read8(adapter, REG_SYS_FUNC_EN),
+				pwrpriv->wowlan_txpause_status);
+	} else {
+		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
+		val8 |= BIT(0);
+		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
+		DBG_871X("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
+				__func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
+				pwrpriv->wowlan_txpause_status);
+		/* release TX*/
+		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
+	}
+}
+
+static void rtw_hal_reset_mac_rx(_adapter *adapter)
+{
+	u8 val8 = 0;
+	/* Set REG_CR bit1, bit3, bit7 to 0*/
+	val8 = rtw_read8(adapter, REG_CR);
+	val8 &= 0x75;
+	rtw_write8(adapter, REG_CR, val8);
+	val8 = rtw_read8(adapter, REG_CR);
+	/* Set REG_CR bit1, bit3, bit7 to 1*/
+	val8 |= 0x8a;
+	rtw_write8(adapter, REG_CR, val8);
+	DBG_871X("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
+}
+
+static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
+{
+	u8 val8 = 0;
+	u16 rxff_bndy = 0;
+	u32 rx_dma_buff_sz = 0;
+
+	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
+	if (val8 != 0)
+		DBG_871X("%s:[%04x]some PKTs in TXPKTBUF\n",
+			 __func__, (REG_FIFOPAGE + 3));
+
+	rtw_hal_reset_mac_rx(adapter);
+
+	if (wow_mode) {
+		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
+				    (u8 *)&rx_dma_buff_sz);
+		rxff_bndy = rx_dma_buff_sz - 1;
+
+		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
+		DBG_871X("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
+			 REG_TRXFF_BNDY + 2,
+			 rtw_read16(adapter, (REG_TRXFF_BNDY+2)));
+	} else {
+		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
+				    (u8 *)&rx_dma_buff_sz);
+		rxff_bndy = rx_dma_buff_sz - 1;
+		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
+		DBG_871X("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
+			 REG_TRXFF_BNDY + 2,
+			 rtw_read16(adapter, (REG_TRXFF_BNDY+2)));
+	}
+}
+
+static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
+			       u8 len, u8 *mask)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+	struct mlme_ext_priv *pmlmeext = NULL;
+	struct mlme_ext_info *pmlmeinfo = NULL;
+	struct rtl_wow_pattern wow_pattern;
+	u8 mask_hw[MAX_WKFM_SIZE] = {0};
+	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
+	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+	u8 multicast_addr1[2] = {0x33, 0x33};
+	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
+	u8 res = _FALSE, index = 0, mask_len = 0;
+	u8 mac_addr[ETH_ALEN] = {0};
+	u16 count = 0;
+	int i, j;
+
+	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_NUM) {
+		DBG_871X("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
+			 __func__, MAX_WKFM_NUM);
+		return _FALSE;
+	}
+
+	pmlmeext = &adapter->mlmeextpriv;
+	pmlmeinfo = &pmlmeext->mlmext_info;
+	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
+	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
+
+	mask_len = DIV_ROUND_UP(len, 8);
+
+	/* 1. setup A1 table */
+	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
+		wow_pattern.type = PATTERN_BROADCAST;
+	else if (memcmp(pattern, multicast_addr1, 2) == 0)
+		wow_pattern.type = PATTERN_MULTICAST;
+	else if (memcmp(pattern, multicast_addr2, 3) == 0)
+		wow_pattern.type = PATTERN_MULTICAST;
+	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
+		wow_pattern.type = PATTERN_UNICAST;
+	else
+		wow_pattern.type = PATTERN_INVALID;
+
+	/* translate mask from os to mask for hw */
+
+/******************************************************************************
+ * pattern from OS uses 'ethenet frame', like this:
+
+	|    6   |    6   |   2  |     20    |  Variable  |  4  |
+	|--------+--------+------+-----------+------------+-----|
+	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
+	|   DA   |   SA   | Type |
+
+ * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
+
+	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
+	|-------------------+--------+------+-----------+------------+-----|
+	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
+			    | Others | Tpye |
+
+ * Therefore, we need translate mask_from_OS to mask_to_hw.
+ * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
+ * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
+ * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
+ ******************************************************************************/
+	/* Shift 6 bits */
+	for (i = 0; i < mask_len - 1; i++) {
+		mask_hw[i] = mask[i] >> 6;
+		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
+	}
+
+	mask_hw[i] = (mask[i] >> 6) & 0x3F;
+	/* Set bit 0-5 to zero */
+	mask_hw[0] &= 0xC0;
+	
+	for (i = 0; i < (MAX_WKFM_SIZE/4); i++) {
+		wow_pattern.mask[i] = mask_hw[i * 4];
+		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
+		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
+		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
+	}
+
+	/* To get the wake up pattern from the mask.
+	 * We do not count first 12 bits which means
+	 * DA[6] and SA[6] in the pattern to match HW design. */
+	count = 0;
+	for (i = 12; i < len; i++) {
+		if ((mask[i / 8] >> (i % 8)) & 0x01) {
+			content[count] = pattern[i];
+			count++;
+		}
+	}
+
+	wow_pattern.crc = rtw_calc_crc(content, count);
+
+	if (wow_pattern.crc != 0) {
+		if (wow_pattern.type == PATTERN_INVALID)
+			wow_pattern.type = PATTERN_VALID;
+	}
+
+	index = rtw_read8(adapter, REG_WKFMCAM_NUM);
+
+	if (!pwrctl->bInSuspend)
+		index += 2;
+
+	/* write pattern */
+	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
+
+	if (res == _TRUE) {
+		pwrctl->wowlan_pattern_idx++;
+		rtw_write8(adapter,
+			   REG_WKFMCAM_NUM,
+			   pwrctl->wowlan_pattern_idx);
+	} else {
+		DBG_871X("%s: ERROR write_to_frame_mask_cam fail\n", __func__);
+	}
+
+	return res;
+}
+
+static void rtw_hal_dl_pattern(_adapter *adapter, u8 clean_all)
+{
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+	int i = 0, total = 0;
+
+	total = pwrpriv->wowlan_pattern_idx;
+
+	rtw_clean_pattern(adapter);
+
+	if (!clean_all) {
+		for (i = 0 ; i < total ; i++) {
+			rtw_hal_set_pattern(adapter,
+					pwrpriv->patterns[i].content,
+					pwrpriv->patterns[i].len,
+					pwrpriv->patterns[i].mask);
+		}
+		DBG_871X("pattern downloaded\n");
+	} else {
+		for (i = 0 ; i < MAX_WKFM_NUM ; i++) {
+			_rtw_memset(pwrpriv->patterns[i].content, '\0',
+					sizeof(pwrpriv->patterns[i].content));
+			_rtw_memset(pwrpriv->patterns[i].mask, '\0',
+					sizeof(pwrpriv->patterns[i].mask));
+			pwrpriv->patterns[i].len = 0;
+		}
+		DBG_871X("clean all pattern\n");
+	}
+}
+
+static void rtw_hal_wow_enable(_adapter *adapter)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+	struct security_priv *psecuritypriv = &adapter->securitypriv;
+	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	struct sta_info *psta = NULL;
+	int res;
+	u16 media_status_rpt;
+	
+
+	DBG_871X_LEVEL(_drv_always_, "%s, WOWLAN_ENABLE\n", __func__);
+	rtw_hal_gate_bb(adapter, _TRUE);
+#ifdef CONFIG_GTK_OL
+	if (psecuritypriv->dot11PrivacyAlgrthm == _AES_)
+		rtw_hal_fw_sync_cam_id(adapter);
+#endif
+	if (IS_HARDWARE_TYPE_8723B(adapter))
+		rtw_hal_backup_rate(adapter);
+
+	/* RX DMA stop */
+	if (IS_HARDWARE_TYPE_8188E(adapter))
+		rtw_hal_disable_tx_report(adapter);
+
+	res = rtw_hal_pause_rx_dma(adapter);
+	if (res == _FAIL)
+		DBG_871X_LEVEL(_drv_always_, "[WARNING] pause RX DMA fail\n");
+
+	/* Reconfig RX_FF Boundary */
+	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
+
+	/* redownload pattern match */
+	if (pwrctl->wowlan_pattern)
+		rtw_hal_dl_pattern(adapter, _FALSE);
+
+	rtw_hal_fw_dl(adapter, _TRUE);
+	media_status_rpt = RT_MEDIA_CONNECT;
+	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
+		(u8 *)&media_status_rpt);
+		
+	if (!pwrctl->wowlan_pno_enable) {
+		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
+		if (psta != NULL)
+			rtw_sta_media_status_rpt(adapter, psta, 1);
+	}
+		
+#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+	/* Enable CPWM2 only. */
+	res = rtw_hal_enable_cpwm2(adapter);
+	if (res == _FAIL)
+		DBG_871X_LEVEL(_drv_always_, "[WARNING] enable cpwm2 fail\n");
+#endif
+#ifdef CONFIG_GPIO_WAKEUP
+	rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);
+#endif
+	/* Set WOWLAN H2C command. */
+	DBG_871X_LEVEL(_drv_always_, "Set WOWLan cmd\n");
+	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
+		
+	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
+
+	if (res == _FALSE)
+		DBG_871X("[Error]%s: set wowlan CMD fail!!\n", __func__);
+
+	pwrctl->wowlan_wake_reason =
+		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
+
+	DBG_871X_LEVEL(_drv_always_, "wowlan_wake_reason: 0x%02x\n",
+				pwrctl->wowlan_wake_reason);
+#ifdef CONFIG_GTK_OL_DBG
+	dump_sec_cam(RTW_DBGDUMP, adapter);
+#endif
+#ifdef CONFIG_USB_HCI
+	if (adapter->intf_stop)	    /* free adapter's resource */
+		adapter->intf_stop(adapter);
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (rtw_buddy_adapter_up(adapter)) /*free buddy adapter's resource*/
+		adapter->pbuddy_adapter->intf_stop(adapter->pbuddy_adapter);
+#endif /*CONFIG_CONCURRENT_MODE*/
+	/* Invoid SE0 reset signal during suspending*/
+	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
+	rtw_write8(adapter, REG_RSV_CTRL, 0x60);
+#endif /*CONFIG_USB_HCI*/
+
+	rtw_hal_gate_bb(adapter, _FALSE);
+}
+
+static void rtw_hal_wow_disable(_adapter *adapter)
+{
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+	struct security_priv *psecuritypriv = &adapter->securitypriv;
+	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	struct sta_info *psta = NULL;
+	int res;
+	u16 media_status_rpt;
+	u8 val8;
+
+	DBG_871X_LEVEL(_drv_always_, "%s, WOWLAN_DISABLE\n", __func__);
+
+	if (!pwrctl->wowlan_pno_enable) {
+		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
+		if (psta != NULL)
+			rtw_sta_media_status_rpt(adapter, psta, 0);
+		else
+			DBG_871X("%s: psta is null\n", __func__);
+	}
+		
+	if (0) {
+		DBG_871X("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
+		DBG_871X("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
+	}
+
+	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
+
+	DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x\n",
+		pwrctl->wowlan_wake_reason);
+
+	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
+
+	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
+
+	if (res == _FALSE) {
+		DBG_871X("[Error]%s: disable WOW cmd fail\n!!", __func__);
+		rtw_hal_force_enable_rxdma(adapter);
+	}
+
+	rtw_hal_gate_bb(adapter, _TRUE);
+
+	res = rtw_hal_pause_rx_dma(adapter);
+	if (res == _FAIL)
+		DBG_871X_LEVEL(_drv_always_, "[WARNING] pause RX DMA fail\n");
+
+	/* clean pattern match */
+	if (pwrctl->wowlan_pattern)
+		rtw_hal_dl_pattern(adapter, _TRUE);
+
+	/* config RXFF boundary to original */
+	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
+
+	rtw_hal_release_rx_dma(adapter);
+
+	if (IS_HARDWARE_TYPE_8188E(adapter))
+		rtw_hal_enable_tx_report(adapter);
+		
+	rtw_hal_update_tx_iv(adapter);
+
+#ifdef CONFIG_GTK_OL
+	if (psecuritypriv->dot11PrivacyAlgrthm == _AES_)
+		rtw_hal_update_gtk_offload_info(adapter);
+#endif /*CONFIG_GTK_OL*/
+
+	rtw_hal_fw_dl(adapter, _FALSE);
+
+#ifdef CONFIG_GPIO_WAKEUP
+	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
+	DBG_871X_LEVEL(_drv_always_, "Set Wake GPIO to default(%d).\n", val8);
+	rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);
+	rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE);
+#endif
+	if ((pwrctl->wowlan_wake_reason != FWDecisionDisconnect) &&
+		(pwrctl->wowlan_wake_reason != Rx_Pairwisekey) &&
+		(pwrctl->wowlan_wake_reason != Rx_DisAssoc) &&
+		(pwrctl->wowlan_wake_reason != Rx_DeAuth)) {
+
+		media_status_rpt = RT_MEDIA_CONNECT;
+		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
+			(u8 *)&media_status_rpt);
+
+		if (psta != NULL)
+			rtw_sta_media_status_rpt(adapter, psta, 1);
+	}
+	rtw_hal_gate_bb(adapter, _FALSE);
+}
+#endif /*CONFIG_WOWLAN*/
+
+#ifdef CONFIG_P2P_WOWLAN
+void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter* adapter, u8 *pframe, u16 index,
+		u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
+		RSVDPAGE_LOC* rsvd_page_loc)
+{
+	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
+	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
+	u8 CurtPktPageNum = 0;
+
+	/* P2P Beacon */
+	rsvd_page_loc->LocP2PBeacon = *page_num;
+	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
+	rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc],
+			P2PBCNLength, _FALSE, _FALSE, _FALSE);
+
+#if 0
+	DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", 
+		__FUNCTION__, &pframe[index-tx_desc], (P2PBCNLength+tx_desc));
+#endif
+
+	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
+
+	*page_num += CurtPktPageNum;
+
+	index += (CurtPktPageNum * page_size);
+
+	// P2P Probe rsp
+	rsvd_page_loc->LocP2PProbeRsp = *page_num;
+	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
+			&P2PProbeRspLength);
+	rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc],
+			P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
+
+	//DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", 
+	//	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc));
+
+	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
+
+	*page_num += CurtPktPageNum;
+
+	index += (CurtPktPageNum * page_size);
+
+	//P2P nego rsp
+	rsvd_page_loc->LocNegoRsp = *page_num;
+	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
+			&P2PNegoRspLength);
+	rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc],
+			P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
+
+	//DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
+	//	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc));
+
+	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
+
+	*page_num += CurtPktPageNum;
+
+	index += (CurtPktPageNum * page_size);
+		
+	//P2P invite rsp
+	rsvd_page_loc->LocInviteRsp = *page_num;
+	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
+			&P2PInviteRspLength);
+	rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc],
+			P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
+
+	//DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
+	//__FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc));
+
+	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
+
+	*page_num += CurtPktPageNum;
+
+	index += (CurtPktPageNum * page_size);
+	
+	//P2P provision discovery rsp
+	rsvd_page_loc->LocPDRsp = *page_num;
+	rtw_hal_construct_P2PProvisionDisRsp( adapter,
+			&pframe[index], &P2PPDRspLength);
+
+	rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc],
+			P2PPDRspLength, _FALSE, _FALSE, _FALSE);
+
+	//DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
+	//	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc));
+
+	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
+
+       *page_num += CurtPktPageNum;
+
+	index += (CurtPktPageNum * page_size);
+
+	*total_pkt_len = index + P2PPDRspLength;
+}
+#endif //CONFIG_P2P_WOWLAN
+
+/*
+ * Description: Fill the reserved packets that FW will use to RSVD page.
+ *			Now we just send 4 types packet to rsvd page.
+ *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
+ * Input:
+ * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
+ *		    so we need to set the packet length to total lengh.
+ *	      TRUE: At the second time, we should send the first packet (default:beacon)
+ *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
+ * 2009.10.15 by tynli.
+ *
+ * Page Size = 128: 8188e, 8723a/b, 8192c/d,  
+ * Page Size = 256: 8192e, 8821a
+ * Page Size = 512: 8812a
+ */
+
+void rtw_hal_set_fw_rsvd_page(_adapter* adapter, bool finished)
+{
+	PHAL_DATA_TYPE pHalData;
+	struct xmit_frame	*pcmdframe;
+	struct pkt_attrib	*pattrib;
+	struct xmit_priv	*pxmitpriv;
+	struct mlme_ext_priv	*pmlmeext;
+	struct mlme_ext_info	*pmlmeinfo;
+	struct pwrctrl_priv *pwrctl;
+	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+	struct hal_ops *pHalFunc = &adapter->HalFunc;
+	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
+	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
+	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
+	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
+	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
+	u8	*ReservedPagePacket;
+	u16	BufIndex = 0;
+	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
+	RSVDPAGE_LOC	RsvdPageLoc;
+
+#ifdef DBG_CONFIG_ERROR_DETECT
+	struct sreset_priv *psrtpriv;
+#endif /* DBG_CONFIG_ERROR_DETECT */
+
+
+	pHalData = GET_HAL_DATA(adapter);
+#ifdef DBG_CONFIG_ERROR_DETECT
+	psrtpriv = &pHalData->srestpriv;
+#endif
+	pxmitpriv = &adapter->xmitpriv;
+	pmlmeext = &adapter->mlmeextpriv;
+	pmlmeinfo = &pmlmeext->mlmext_info;
+	pwrctl = adapter_to_pwrctl(adapter);
+
+	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
+	
+	if (PageSize == 0) {
+		DBG_871X("[Error]: %s, PageSize is zero!!\n", __func__);
+		return;
+	}
+
+	if (pwrctl->wowlan_mode == _TRUE || pwrctl->wowlan_ap_mode == _TRUE)
+		RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
+	else
+		RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
+	
+	DBG_871X("%s PageSize: %d, RsvdPageNUm: %d\n",__func__, PageSize, RsvdPageNum);
+	
+	MaxRsvdPageBufSize = RsvdPageNum*PageSize;
+
+	if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
+		DBG_871X("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
+			__func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
+		rtw_warn_on(1);
+		return;
+	}
+	
+	pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
+	
+	if (pcmdframe == NULL) {
+		DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
+		return;
+	}
+
+	ReservedPagePacket = pcmdframe->buf_addr;
+	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
+
+	/* beacon * 2 pages */
+	BufIndex = TxDescOffset;
+	rtw_hal_construct_beacon(adapter,
+			&ReservedPagePacket[BufIndex], &BeaconLength);
+
+	/*
+	* When we count the first page size, we need to reserve description size for the RSVD
+	* packet, it will be filled in front of the packet in TXPKTBUF.
+	*/
+	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
+	/* If we don't add 1 more page, ARP offload function will fail at 8723bs.*/
+	if (CurtPktPageNum == 1) 
+		CurtPktPageNum += 1;
+
+	TotalPageNum += CurtPktPageNum;
+
+	BufIndex += (CurtPktPageNum*PageSize);
+
+	if (pwrctl->wowlan_ap_mode == _TRUE) {
+		/* (4) probe response*/
+		RsvdPageLoc.LocProbeRsp = TotalPageNum;
+		rtw_hal_construct_ProbeRsp(
+			adapter, &ReservedPagePacket[BufIndex],
+			&ProbeRspLength,
+			get_my_bssid(&pmlmeinfo->network), _FALSE);
+		rtw_hal_fill_fake_txdesc(adapter,
+			&ReservedPagePacket[BufIndex-TxDescLen],
+			ProbeRspLength, _FALSE, _FALSE, _FALSE);
+
+		CurtPktPageNum = (u8)PageNum(TxDescLen + BeaconLength, PageSize);
+		TotalPageNum += CurtPktPageNum;
+		BufIndex += (CurtPktPageNum*PageSize);
+		TotalPacketLen = BufIndex + ProbeRspLength;
+		goto download_page;
+	}
+
+	/* ps-poll * 1 page */
+	RsvdPageLoc.LocPsPoll = TotalPageNum;
+	DBG_871X("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
+	rtw_hal_construct_PSPoll(adapter,
+			&ReservedPagePacket[BufIndex], &PSPollLength);
+	rtw_hal_fill_fake_txdesc(adapter,
+			&ReservedPagePacket[BufIndex-TxDescLen],
+			PSPollLength, _TRUE, _FALSE, _FALSE);
+
+	CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
+
+	TotalPageNum += CurtPktPageNum;
+
+	BufIndex += (CurtPktPageNum*PageSize);
+
+#ifdef CONFIG_BT_COEXIST
+	/* BT Qos null data * 1 page */
+	RsvdPageLoc.LocBTQosNull = TotalPageNum;
+	DBG_871X("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
+	rtw_hal_construct_NullFunctionData(
+			adapter,
+			&ReservedPagePacket[BufIndex],
+			&BTQosNullLength,
+			get_my_bssid(&pmlmeinfo->network),
+			_TRUE, 0, 0, _FALSE);
+	rtw_hal_fill_fake_txdesc(adapter,
+			&ReservedPagePacket[BufIndex-TxDescLen],
+			BTQosNullLength, _FALSE, _TRUE, _FALSE);
+
+	CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize);
+
+	TotalPageNum += CurtPktPageNum;
+
+	BufIndex += (CurtPktPageNum*PageSize);
+#endif /* CONFIG_BT_COEXIT */
+
+	/* null data * 1 page */
+	RsvdPageLoc.LocNullData = TotalPageNum;
+	DBG_871X("LocNullData: %d\n", RsvdPageLoc.LocNullData);
+	rtw_hal_construct_NullFunctionData(
+			adapter,
+			&ReservedPagePacket[BufIndex],
+			&NullDataLength,
+			get_my_bssid(&pmlmeinfo->network),
+			_FALSE, 0, 0, _FALSE);
+	rtw_hal_fill_fake_txdesc(adapter,
+			&ReservedPagePacket[BufIndex-TxDescLen],
+			NullDataLength, _FALSE, _FALSE, _FALSE);
+
+	CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
+
+	TotalPageNum += CurtPktPageNum;
+
+	BufIndex += (CurtPktPageNum*PageSize);
+
+	//Qos null data * 1 page
+	RsvdPageLoc.LocQosNull = TotalPageNum;
+	DBG_871X("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
+	rtw_hal_construct_NullFunctionData(
+			adapter,
+			&ReservedPagePacket[BufIndex],
+			&QosNullLength,
+			get_my_bssid(&pmlmeinfo->network),
+			_TRUE, 0, 0, _FALSE);
+	rtw_hal_fill_fake_txdesc(adapter,
+			&ReservedPagePacket[BufIndex-TxDescLen],
+			QosNullLength, _FALSE, _FALSE, _FALSE);
+
+	CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength, PageSize);
+
+	TotalPageNum += CurtPktPageNum;
+
+	BufIndex += (CurtPktPageNum*PageSize);
+
+	TotalPacketLen = BufIndex + QosNullLength;
+#ifdef CONFIG_WOWLAN
+	if (pwrctl->wowlan_mode == _TRUE &&
+			check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
+		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
+				BufIndex, TxDescLen, PageSize,
+				&TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
+	}
+#endif /* CONFIG_WOWLAN */
+
+#ifdef CONFIG_P2P_WOWLAN
+	if(_TRUE == pwrctl->wowlan_p2p_mode) {
+		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
+				BufIndex, TxDescLen, PageSize,
+				&TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
+	}
+#endif /* CONFIG_P2P_WOWLAN */
+
+download_page:
+	DBG_871X("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",
+				__func__, BufIndex, TxDescLen, PageSize);
+	DBG_871X("%s PageNum(%d), pktlen(%d)\n",
+				__func__, TotalPageNum, TotalPacketLen);
+
+	if (TotalPacketLen > MaxRsvdPageBufSize) {
+		DBG_871X("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
+				__FUNCTION__, TotalPacketLen,MaxRsvdPageBufSize);
+		rtw_warn_on(1);
+		goto error;
+	} else {
+		/* update attribute */
+		pattrib = &pcmdframe->attrib;
+		update_mgntframe_attrib(adapter, pattrib);
+		pattrib->qsel = QSLT_BEACON;
+		pattrib->pktlen = TotalPacketLen - TxDescOffset;
+		pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
+#ifdef CONFIG_PCI_HCI
+		dump_mgntframe(adapter, pcmdframe);
+#else
+		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
+#endif
+	}
+
+	DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
+			__func__,TotalPacketLen,TotalPageNum);
+
+	if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
+		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
+		if (pwrctl->wowlan_mode == _TRUE)
+			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
+#ifdef CONFIG_AP_WOWLAN
+		if (pwrctl->wowlan_ap_mode == _TRUE)
+			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
+#endif /* CONFIG_AP_WOWLAN */
+	} else if (pwrctl->wowlan_pno_enable) {
+#ifdef CONFIG_PNO_SUPPORT
+		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
+		if(pwrctl->pno_in_resume)
+			rtw_hal_set_scan_offload_info_cmd(adapter,
+					&RsvdPageLoc, 0);
+		else
+			rtw_hal_set_scan_offload_info_cmd(adapter,
+					&RsvdPageLoc, 1);
+#endif /* CONFIG_PNO_SUPPORT */
+	}
+#ifdef CONFIG_P2P_WOWLAN
+	if(_TRUE == pwrctl->wowlan_p2p_mode)
+		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
+#endif /* CONFIG_P2P_WOWLAN */
+	return;
+error:
+	rtw_free_xmitframe(pxmitpriv, pcmdframe);
+}
+
+void SetHwReg(_adapter *adapter, u8 variable, u8 *val)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+_func_enter_;
+
+	switch (variable) {
+		case HW_VAR_PORT_SWITCH:
+			hw_var_port_switch(adapter);
+			break;
+		case HW_VAR_INIT_RTS_RATE:
+		{
+			u16 brate_cfg = *((u16*)val);
+			u8 rate_index = 0;
+			HAL_VERSION *hal_ver = &hal_data->VersionID;
+
+			if (IS_8188E(*hal_ver)) {
+
+				while (brate_cfg > 0x1) {
+					brate_cfg = (brate_cfg >> 1);
+					rate_index++;
+				}
+				rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
+			} else {
+				rtw_warn_on(1);
+			}
+		}
+			break;
+		case HW_VAR_SEC_CFG:
+		{
+			#if defined(CONFIG_CONCURRENT_MODE) && !defined(DYNAMIC_CAMID_ALLOC)
+			// enable tx enc and rx dec engine, and no key search for MC/BC
+			rtw_write8(adapter, REG_SECCFG, SCR_NoSKMC|SCR_RxDecEnable|SCR_TxEncEnable);
+			#elif defined(DYNAMIC_CAMID_ALLOC)
+			u16 reg_scr_ori;
+			u16 reg_scr;
+
+			reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
+			reg_scr |= (SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable);
+
+			if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
+				reg_scr |= SCR_CHK_BMC;
+
+			if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
+				reg_scr |= SCR_NoSKMC;
+
+			if (reg_scr != reg_scr_ori)
+				rtw_write16(adapter, REG_SECCFG, reg_scr);
+			#else
+			rtw_write8(adapter, REG_SECCFG, *((u8*)val));
+			#endif
+		}
+			break;
+		case HW_VAR_SEC_DK_CFG:
+		{
+			struct security_priv *sec = &adapter->securitypriv;
+			u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
+
+			if (val) /* Enable default key related setting */
+			{
+				reg_scr |= SCR_TXBCUSEDK;
+				if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
+					reg_scr |= (SCR_RxUseDK|SCR_TxUseDK);
+			}
+			else /* Disable default key related setting */
+			{
+				reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK);
+			}
+
+			rtw_write8(adapter, REG_SECCFG, reg_scr);
+		}
+			break;
+
+		case HW_VAR_ASIX_IOT:
+			// enable  ASIX IOT function
+			if (*((u8*)val) == _TRUE) {
+				// 0xa2e[0]=0 (disable rake receiver)
+				rtw_write8(adapter, rCCK0_FalseAlarmReport+2, 
+						rtw_read8(adapter, rCCK0_FalseAlarmReport+2) & ~(BIT0));
+				//  0xa1c=0xa0 (reset channel estimation if signal quality is bad)
+				rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
+			} else {
+			// restore reg:0xa2e,   reg:0xa1c
+				rtw_write8(adapter, rCCK0_FalseAlarmReport+2, 
+						rtw_read8(adapter, rCCK0_FalseAlarmReport+2)|(BIT0));
+				rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
+			}
+			break;
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+		case HW_VAR_WOWLAN:
+		{
+			struct wowlan_ioctl_param *poidparam;
+			
+			poidparam = (struct wowlan_ioctl_param *)val;
+			switch (poidparam->subcode) {
+#ifdef CONFIG_WOWLAN
+			case WOWLAN_PATTERN_CLEAN:
+				rtw_hal_dl_pattern(adapter, _TRUE);
+				break;
+			case WOWLAN_ENABLE:
+				rtw_hal_wow_enable(adapter);
+				break;
+			case WOWLAN_DISABLE:
+				rtw_hal_wow_disable(adapter);
+				break;
+#endif /*CONFIG_WOWLAN*/
+#ifdef CONFIG_AP_WOWLAN
+			case WOWLAN_AP_ENABLE:
+				rtw_hal_ap_wow_enable(adapter);
+				break;
+			case WOWLAN_AP_DISABLE:
+				rtw_hal_ap_wow_disable(adapter);
+				break;
+#endif /*CONFIG_AP_WOWLAN*/
+			default:
+				break;
+			}
+		}
+		break;
+#endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
+		default:
+			if (0)
+				DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" variable(%d) not defined!\n",
+					FUNC_ADPT_ARG(adapter), variable);
+			break;
+	}
+
+_func_exit_;
+}
+
+void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+_func_enter_;
+
+	switch (variable) {
+	case HW_VAR_BASIC_RATE:
+		*((u16*)val) = hal_data->BasicRateSet;
+		break;
+	case HW_VAR_RF_TYPE:
+		*((u8*)val) = hal_data->rf_type;
+		break;
+	default:
+		if (0)
+			DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" variable(%d) not defined!\n",
+				FUNC_ADPT_ARG(adapter), variable);
+		break;
+	}
+
+_func_exit_;
+}
+
+u8
+SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
+{	
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	u8 bResult = _SUCCESS;
+
+	switch(variable) {
+
+	case HAL_DEF_DBG_DUMP_RXPKT:
+		hal_data->bDumpRxPkt = *((u8*)value);
+		break;
+	case HAL_DEF_DBG_DUMP_TXPKT:
+		hal_data->bDumpTxPkt = *((u8*)value);
+		break;
+	case HAL_DEF_ANT_DETECT:
+		hal_data->AntDetection = *((u8 *)value);
+		break;
+	case HAL_DEF_DBG_DIS_PWT:
+		hal_data->bDisableTXPowerTraining = *((u8*)value);
+		break;	
+	default:
+		DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
+		bResult = _FAIL;
+		break;
+	}
+
+	return bResult;
+}
+
+#ifdef CONFIG_BEAMFORMING
+u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
+{
+	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	
+	if ((pregistrypriv->beamformer_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter)))
+		return pregistrypriv->beamformer_rf_num;
+	else if (IS_HARDWARE_TYPE_8814AE(adapter)
+/*
+#if defined(CONFIG_USB_HCI) 
+	||  (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) //for USB3.0
+#endif
+*/
+	) {	
+		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
+		if (hal_data->rf_type == RF_3T3R) 
+			return 2;
+		else if (hal_data->rf_type == RF_4T4R)
+			return 3;
+		else 
+			return 1;
+	} else
+		return 1;
+	
+}
+u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
+{
+	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
+	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	
+	if ((pregistrypriv->beamformee_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter)))
+		return pregistrypriv->beamformee_rf_num;
+	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
+		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)		
+			return 2;		
+		else
+			return 2;/*TODO: May be 3 in the future, by ChenYu. */
+	} else
+		return 1;
+		
+}
+#endif
+
+u8
+GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	u8 bResult = _SUCCESS;
+
+	switch(variable) {
+		case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
+			{
+				struct mlme_priv *pmlmepriv;
+				struct sta_priv *pstapriv;
+				struct sta_info *psta;
+
+				pmlmepriv = &adapter->mlmepriv;
+				pstapriv = &adapter->stapriv;
+				psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
+				if (psta)
+				{
+					*((int*)value) = psta->rssi_stat.UndecoratedSmoothedPWDB;     
+				}
+			}
+			break;
+		case HAL_DEF_DBG_DUMP_RXPKT:
+			*((u8*)value) = hal_data->bDumpRxPkt;
+			break;
+		case HAL_DEF_DBG_DUMP_TXPKT:
+			*((u8*)value) = hal_data->bDumpTxPkt;
+			break;
+		case HAL_DEF_ANT_DETECT:
+			*((u8 *)value) = hal_data->AntDetection;
+			break;
+		case HAL_DEF_MACID_SLEEP:
+			*(u8*)value = _FALSE;
+			break;
+		case HAL_DEF_TX_PAGE_SIZE:
+			*(( u32*)value) = PAGE_SIZE_128;
+			break;
+		case HAL_DEF_DBG_DIS_PWT:
+			*(u8*)value = hal_data->bDisableTXPowerTraining;
+			break;
+#ifdef CONFIG_BEAMFORMING
+		case HAL_DEF_BEAMFORMER_CAP:
+			*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
+			break;
+		case HAL_DEF_BEAMFORMEE_CAP:
+			*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
+			break;
+#endif
+		default:
+			DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
+			bResult = _FAIL;
+			break;
+	}
+
+	return bResult;
+}
+
+void SetHalODMVar(
+	PADAPTER				Adapter,
+	HAL_ODM_VARIABLE		eVariable,
+	PVOID					pValue1,
+	BOOLEAN					bSet)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T podmpriv = &pHalData->odmpriv;
+	//_irqL irqL;
+	switch(eVariable){
+		case HAL_ODM_STA_INFO:
+			{	
+				struct sta_info *psta = (struct sta_info *)pValue1;				
+				if(bSet){
+					DBG_8192C("### Set STA_(%d) info ###\n",psta->mac_id);
+					ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,psta);
+				}
+				else{
+					DBG_8192C("### Clean STA_(%d) info ###\n",psta->mac_id);
+					//_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL);
+					ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,NULL);
+					
+					//_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL);
+			            }
+			}
+			break;
+		case HAL_ODM_P2P_STATE:		
+				ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DIRECT,bSet);
+			break;
+		case HAL_ODM_WIFI_DISPLAY_STATE:
+				ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DISPLAY,bSet);
+			break;
+		case HAL_ODM_REGULATION:
+				ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G);
+				ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G);
+			break;
+#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)		
+		case HAL_ODM_NOISE_MONITOR:
+			{
+				struct noise_info *pinfo = (struct noise_info *)pValue1;
+
+				#ifdef DBG_NOISE_MONITOR
+				DBG_8192C("### Noise monitor chan(%d)-bPauseDIG:%d,IGIValue:0x%02x,max_time:%d (ms) ###\n",
+					pinfo->chan,pinfo->bPauseDIG,pinfo->IGIValue,pinfo->max_time);
+				#endif
+				
+				pHalData->noise[pinfo->chan] = ODM_InbandNoise_Monitor(podmpriv,pinfo->bPauseDIG,pinfo->IGIValue,pinfo->max_time);				
+				DBG_871X("chan_%d, noise = %d (dBm)\n",pinfo->chan,pHalData->noise[pinfo->chan]);
+				#ifdef DBG_NOISE_MONITOR
+				DBG_871X("noise_a = %d, noise_b = %d  noise_all:%d \n", 
+					podmpriv->noise_level.noise[ODM_RF_PATH_A], 
+					podmpriv->noise_level.noise[ODM_RF_PATH_B],
+					podmpriv->noise_level.noise_all);						
+				#endif
+			}
+			break;
+#endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
+
+		case HAL_ODM_INITIAL_GAIN:
+			{
+				u8 rx_gain = *((u8 *)(pValue1));
+				/*printk("rx_gain:%x\n",rx_gain);*/
+				if (rx_gain == 0xff) {/*restore rx gain*/
+					/*ODM_Write_DIG(podmpriv,pDigTable->BackupIGValue);*/
+					odm_PauseDIG(podmpriv, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, rx_gain);
+				} else {
+					/*pDigTable->BackupIGValue = pDigTable->CurIGValue;*/
+					/*ODM_Write_DIG(podmpriv,rx_gain);*/
+					odm_PauseDIG(podmpriv, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, rx_gain);
+				}
+			}
+			break;		
+		case HAL_ODM_FA_CNT_DUMP:
+			if (*((u8 *)pValue1))
+				podmpriv->DebugComponents |= (ODM_COMP_DIG | ODM_COMP_FA_CNT);
+			else
+				podmpriv->DebugComponents &= ~(ODM_COMP_DIG | ODM_COMP_FA_CNT);
+			break;
+		case HAL_ODM_DBG_FLAG:
+			ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_DBG_COMP, *((u8Byte *)pValue1));
+			break;
+		case HAL_ODM_DBG_LEVEL:
+			ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_DBG_LEVEL, *((u4Byte *)pValue1));
+			break;
+		case HAL_ODM_RX_INFO_DUMP:
+		{
+			PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure(podmpriv , PHYDM_FALSEALMCNT);
+			pDIG_T	pDM_DigTable = &podmpriv->DM_DigTable;
+
+			DBG_871X("============ Rx Info dump ===================\n");
+			DBG_871X("bLinked = %d, RSSI_Min = %d(%%), CurrentIGI = 0x%x\n",
+				podmpriv->bLinked, podmpriv->RSSI_Min, pDM_DigTable->CurIGValue);			
+			if (FalseAlmCnt)
+				DBG_871X("Cnt_Cck_fail = %d, Cnt_Ofdm_fail = %d, Total False Alarm = %d\n",
+					FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_all);
+
+			if (podmpriv->bLinked) {
+				DBG_871X("RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n", 
+					HDATA_RATE(podmpriv->RxRate), podmpriv->RSSI_A, podmpriv->RSSI_B);	
+
+				#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
+				rtw_dump_raw_rssi_info(Adapter);
+				#endif
+			}
+		}		
+		break;
+
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM
+		case HAL_ODM_AUTO_CHNL_SEL:
+		{
+			ACS_OP	acs_op = *(ACS_OP *)pValue1;
+
+			rtw_phydm_func_set(Adapter, ODM_BB_NHM_CNT);
+
+			if (ACS_INIT == acs_op) {
+				#ifdef DBG_AUTO_CHNL_SEL_NHM
+				DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_INIT\n", ADPT_ARG(Adapter));
+				#endif
+				odm_AutoChannelSelectInit(podmpriv); 
+			} else if (ACS_RESET == acs_op) {
+				/* Reset statistics for auto channel selection mechanism.*/
+				#ifdef DBG_AUTO_CHNL_SEL_NHM
+				DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_RESET\n", ADPT_ARG(Adapter));
+				#endif
+				odm_AutoChannelSelectReset(podmpriv);
+				
+			} else if (ACS_SELECT == acs_op) {
+				/* Collect NHM measurement result after current channel */
+				#ifdef DBG_AUTO_CHNL_SEL_NHM
+				DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_SELECT, CH(%d)\n", ADPT_ARG(Adapter), rtw_get_acs_channel(Adapter));
+				#endif
+				odm_AutoChannelSelect(podmpriv, rtw_get_acs_channel(Adapter));
+			} else 
+				DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: Unexpected OP\n", ADPT_ARG(Adapter));
+
+		}
+		break;
+#endif
+
+		default:
+			break;
+	}
+}	
+
+void GetHalODMVar(	
+	PADAPTER				Adapter,
+	HAL_ODM_VARIABLE		eVariable,
+	PVOID					pValue1,
+	PVOID					pValue2)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T podmpriv = &pHalData->odmpriv;
+	
+	switch (eVariable) {
+#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
+	case HAL_ODM_NOISE_MONITOR:
+		{
+			u8 chan = *(u8 *)pValue1;
+			*(s16 *)pValue2 = pHalData->noise[chan];
+			#ifdef DBG_NOISE_MONITOR
+			DBG_8192C("### Noise monitor chan(%d)-noise:%d (dBm) ###\n",
+				chan, pHalData->noise[chan]);
+			#endif
+		}
+		break;
+#endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
+	case HAL_ODM_DBG_FLAG:
+		*((u8Byte *)pValue1) = podmpriv->DebugComponents;
+		break;
+	case HAL_ODM_DBG_LEVEL:
+		*((u4Byte *)pValue1) = podmpriv->DebugLevel;
+		break;
+
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM
+	case HAL_ODM_AUTO_CHNL_SEL:
+		{
+			#ifdef DBG_AUTO_CHNL_SEL_NHM
+			DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: GET_BEST_CHAN\n", ADPT_ARG(Adapter));
+			#endif	
+			/* Retrieve better channel from NHM mechanism	*/
+			if (IsSupported24G(Adapter->registrypriv.wireless_mode)) 
+				*((u8 *)(pValue1)) = ODM_GetAutoChannelSelectResult(podmpriv, BAND_ON_2_4G);
+			if (IsSupported5G(Adapter->registrypriv.wireless_mode)) 
+				*((u8 *)(pValue2)) = ODM_GetAutoChannelSelectResult(podmpriv, BAND_ON_5G);
+		}
+		break;
+#endif
+		
+	default:
+		break;
+	}
+}
+
+
+u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+	PDM_ODM_T podmpriv = &pHalData->odmpriv;
+	u32 result = 0;
+	
+	switch (ops) {
+	case HAL_PHYDM_DIS_ALL_FUNC:
+		podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE;
+		break;
+	case HAL_PHYDM_FUNC_SET:
+		podmpriv->SupportAbility |= ability;
+		break;
+	case HAL_PHYDM_FUNC_CLR:
+		podmpriv->SupportAbility &= ~(ability);
+		break;			
+	case HAL_PHYDM_ABILITY_BK:
+		/* dm flag backup*/
+		podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
+		break;
+	case HAL_PHYDM_ABILITY_RESTORE:
+		/* restore dm flag */
+		podmpriv->SupportAbility = podmpriv->BK_SupportAbility;
+		break;
+	case HAL_PHYDM_ABILITY_SET:
+		podmpriv->SupportAbility = ability;
+		break;
+	case HAL_PHYDM_ABILITY_GET:
+		result = podmpriv->SupportAbility;
+		break;
+	}
+	return result;
+}
+
+
+BOOLEAN 
+eqNByte(
+	u8*	str1,
+	u8*	str2,
+	u32	num
+	)
+{
+	if(num==0)
+		return _FALSE;
+	while(num>0)
+	{
+		num--;
+		if(str1[num]!=str2[num])
+			return _FALSE;
+	}
+	return _TRUE;
+}
+
+//
+//	Description:
+//		Return TRUE if chTmp is represent for hex digit and 
+//		FALSE otherwise.
+//
+//
+BOOLEAN
+IsHexDigit(
+	IN		char		chTmp
+)
+{
+	if( (chTmp >= '0' && chTmp <= '9') ||  
+		(chTmp >= 'a' && chTmp <= 'f') ||
+		(chTmp >= 'A' && chTmp <= 'F') )
+	{
+		return _TRUE;
+	}
+	else
+	{
+		return _FALSE;
+	}
+}
+
+
+//
+//	Description:
+//		Translate a character to hex digit.
+//
+u32
+MapCharToHexDigit(
+	IN		char		chTmp
+)
+{
+	if(chTmp >= '0' && chTmp <= '9')
+		return (chTmp - '0');
+	else if(chTmp >= 'a' && chTmp <= 'f')
+		return (10 + (chTmp - 'a'));
+	else if(chTmp >= 'A' && chTmp <= 'F') 
+		return (10 + (chTmp - 'A'));
+	else
+		return 0;	
+}
+
+
+
+//
+//	Description:
+//		Parse hex number from the string pucStr.
+//
+BOOLEAN 
+GetHexValueFromString(
+	IN		char*			szStr,
+	IN OUT	u32*			pu4bVal,
+	IN OUT	u32*			pu4bMove
+)
+{
+	char*		szScan = szStr;
+
+	// Check input parameter.
+	if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL)
+	{
+		DBG_871X("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
+		return _FALSE;
+	}
+
+	// Initialize output.
+	*pu4bMove = 0;
+	*pu4bVal = 0;
+
+	// Skip leading space.
+	while(	*szScan != '\0' && 
+			(*szScan == ' ' || *szScan == '\t') )
+	{
+		szScan++;
+		(*pu4bMove)++;
+	}
+
+	// Skip leading '0x' or '0X'.
+	if(*szScan == '0' && (*(szScan+1) == 'x' || *(szScan+1) == 'X'))
+	{
+		szScan += 2;
+		(*pu4bMove) += 2;
+	}	
+
+	// Check if szScan is now pointer to a character for hex digit, 
+	// if not, it means this is not a valid hex number.
+	if(!IsHexDigit(*szScan))
+	{
+		return _FALSE;
+	}
+
+	// Parse each digit.
+	do
+	{
+		(*pu4bVal) <<= 4;
+		*pu4bVal += MapCharToHexDigit(*szScan);
+
+		szScan++;
+		(*pu4bMove)++;
+	} while(IsHexDigit(*szScan));
+
+	return _TRUE;
+}
+
+BOOLEAN 
+GetFractionValueFromString(
+	IN		char*			szStr,
+	IN OUT	u8*				pInteger,
+	IN OUT	u8*				pFraction,
+	IN OUT	u32*			pu4bMove
+)
+{
+	char	*szScan = szStr;
+
+	// Initialize output.
+	*pu4bMove = 0;
+	*pInteger = 0;
+	*pFraction = 0;
+
+	// Skip leading space.
+	while (	*szScan != '\0' && 	(*szScan == ' ' || *szScan == '\t') ) {
+		++szScan;
+		++(*pu4bMove);
+	}
+
+	// Parse each digit.
+	do {
+		(*pInteger) *= 10;
+		*pInteger += ( *szScan - '0' );
+
+		++szScan;
+		++(*pu4bMove);
+
+		if ( *szScan == '.' ) 
+		{
+			++szScan;
+			++(*pu4bMove);
+			
+			if ( *szScan < '0' || *szScan > '9' )
+				return _FALSE;
+			else {
+				*pFraction = *szScan - '0';
+				++szScan;
+				++(*pu4bMove);
+				return _TRUE;
+			}
+		}
+	} while(*szScan >= '0' && *szScan <= '9');
+
+	return _TRUE;
+}
+
+//
+//	Description:
+//		Return TRUE if szStr is comment out with leading "//".
+//
+BOOLEAN
+IsCommentString(
+	IN		char			*szStr
+)
+{
+	if(*szStr == '/' && *(szStr+1) == '/')
+	{
+		return _TRUE;
+	}
+	else
+	{
+		return _FALSE;
+	}
+}
+
+BOOLEAN
+GetU1ByteIntegerFromStringInDecimal(
+	IN		char*	Str,
+	IN OUT	u8*		pInt
+	)
+{
+	u16 i = 0;
+	*pInt = 0;
+
+	while ( Str[i] != '\0' )
+	{
+		if ( Str[i] >= '0' && Str[i] <= '9' )
+		{
+			*pInt *= 10;
+			*pInt += ( Str[i] - '0' );
+		}
+		else
+		{
+			return _FALSE;
+		}
+		++i;
+	}
+
+	return _TRUE;
+}
+
+// <20121004, Kordan> For example, 
+// ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
+// If RightQualifier does not exist, it will hang on in the while loop
+BOOLEAN 
+ParseQualifiedString(
+    IN		char*	In, 
+    IN OUT	u32*	Start, 
+    OUT		char*	Out, 
+    IN		char		LeftQualifier, 
+    IN		char		RightQualifier
+    )
+{
+	u32	i = 0, j = 0;
+	char	c = In[(*Start)++];
+
+	if (c != LeftQualifier)
+		return _FALSE;
+
+	i = (*Start);
+	while ((c = In[(*Start)++]) != RightQualifier) 
+		; // find ']'
+	j = (*Start) - 2;
+	strncpy((char *)Out, (const char*)(In+i), j-i+1);
+
+	return _TRUE;
+}
+
+BOOLEAN
+isAllSpaceOrTab(
+	u8*	data,
+	u8	size
+	)
+{
+	u8	cnt = 0, NumOfSpaceAndTab = 0;
+
+	while( size > cnt )
+	{
+		if ( data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0' )
+			++NumOfSpaceAndTab;
+
+		++cnt;
+	}
+
+	return size == NumOfSpaceAndTab;
+}
+
+
+void rtw_hal_check_rxfifo_full(_adapter *adapter)
+{
+	struct dvobj_priv *psdpriv = adapter->dvobj;
+	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(adapter);
+	int save_cnt=_FALSE;
+	
+	//switch counter to RX fifo
+	if (IS_8188E(pHalData->VersionID) || IS_8188F(pHalData->VersionID)
+		|| IS_8812_SERIES(pHalData->VersionID) || IS_8821_SERIES(pHalData->VersionID)
+		|| IS_8723B_SERIES(pHalData->VersionID) || IS_8192E(pHalData->VersionID) || IS_8703B_SERIES(pHalData->VersionID))
+	{
+		rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0);
+		save_cnt = _TRUE;
+	}
+	else 
+	{
+		//todo: other chips 
+	}
+	
+		
+	if (save_cnt) {
+		pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
+		pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
+		pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow;
+	} else {
+		/* special value to indicate no implementation */
+		pdbgpriv->dbg_rx_fifo_last_overflow = 1;
+		pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
+		pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
+	}
+}
+
+void linked_info_dump(_adapter *padapter,u8 benable)
+{			
+	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
+
+	if(padapter->bLinkInfoDump == benable)
+		return;
+	
+	DBG_871X("%s %s \n",__FUNCTION__,(benable)?"enable":"disable");
+										
+	if(benable){
+		#ifdef CONFIG_LPS
+		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;//keep org value
+		rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
+		#endif	
+								
+		#ifdef CONFIG_IPS	
+		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;//keep org value
+		rtw_pm_set_ips(padapter,IPS_NONE);
+		#endif	
+	}
+	else{
+		#ifdef CONFIG_IPS		
+		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
+		#endif // CONFIG_IPS
+
+		#ifdef CONFIG_LPS	
+		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt );
+		#endif // CONFIG_LPS
+	}
+	padapter->bLinkInfoDump = benable ;	
+}
+
+#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
+void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
+{
+	u8 isCCKrate,rf_path;
+	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
+	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
+	
+	DBG_871X_SEL_NL(sel,"RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", 
+			HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
+	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M)?TRUE :FALSE;
+
+	if(isCCKrate)
+		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
+		
+	for(rf_path = 0;rf_path<pHalData->NumTotalRFPath;rf_path++)
+	{
+		DBG_871X_SEL_NL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
+			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
+		
+		if(!isCCKrate){
+			DBG_871X_SEL_NL(sel,"\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
+			psample_pkt_rssi->ofdm_pwr[rf_path],psample_pkt_rssi->ofdm_snr[rf_path]);
+		}
+	}	
+}
+
+void rtw_dump_raw_rssi_info(_adapter *padapter)
+{
+	u8 isCCKrate,rf_path;
+	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
+	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
+	DBG_871X("============ RAW Rx Info dump ===================\n");
+	DBG_871X("RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", 
+			HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);	
+
+	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M)?TRUE :FALSE;
+
+	if(isCCKrate)
+		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
+		
+	for(rf_path = 0;rf_path<pHalData->NumTotalRFPath;rf_path++)
+	{
+		DBG_871X("RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
+			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
+		
+		if(!isCCKrate){
+			printk(",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
+			psample_pkt_rssi->ofdm_pwr[rf_path],psample_pkt_rssi->ofdm_snr[rf_path]);
+		}else{
+			printk("\n");	
+		}
+	}	
+}
+
+void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)	
+{
+	u8 isCCKrate,rf_path;
+	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
+	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
+
+	PODM_PHY_INFO_T pPhyInfo  = (PODM_PHY_INFO_T)(&pattrib->phy_info);
+	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
+	
+	psample_pkt_rssi->data_rate = pattrib->data_rate;
+	isCCKrate = (pattrib->data_rate <= DESC_RATE11M)?TRUE :FALSE;
+	
+	psample_pkt_rssi->pwdball = pPhyInfo->RxPWDBAll;
+	psample_pkt_rssi->pwr_all = pPhyInfo->RecvSignalPower;
+
+	for(rf_path = 0;rf_path<pHalData->NumTotalRFPath;rf_path++)
+	{		
+		psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->RxMIMOSignalStrength[rf_path];
+		psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->RxMIMOSignalQuality[rf_path];
+		if(!isCCKrate){
+			psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path];
+			psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];		
+		}
+	}
+}
+#endif
+
+int check_phy_efuse_tx_power_info_valid(PADAPTER padapter) {
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	u8* pContent = pHalData->efuse_eeprom_data;
+	int index = 0;
+	u16 tx_index_offset = 0x0000;
+
+	switch (rtw_get_chip_type(padapter)) {
+		case RTL8723B:
+			tx_index_offset = EEPROM_TX_PWR_INX_8723B;
+		break;
+		case RTL8703B:
+			tx_index_offset = EEPROM_TX_PWR_INX_8703B;
+		break;
+		case RTL8188E:
+			tx_index_offset = EEPROM_TX_PWR_INX_88E;
+		break;
+		case RTL8188F:
+			tx_index_offset = EEPROM_TX_PWR_INX_8188F;
+		break;
+		case RTL8192E:
+			tx_index_offset = EEPROM_TX_PWR_INX_8192E;
+		break;
+		case RTL8821:
+			tx_index_offset = EEPROM_TX_PWR_INX_8821;
+		break;
+		case RTL8812:
+			tx_index_offset = EEPROM_TX_PWR_INX_8812;
+		break;
+		case RTL8814A:
+			tx_index_offset = EEPROM_TX_PWR_INX_8814;
+		break;
+		default:
+			tx_index_offset = 0x0010;
+		break;
+	}
+
+	/* TODO: chacking length by ICs */
+	for (index = 0 ; index < 11 ; index++) {
+		if (pContent[tx_index_offset + index] == 0xFF)
+			return _FALSE;
+	}
+	return _TRUE;
+}
+
+int hal_efuse_macaddr_offset(_adapter *adapter)
+{
+	u8 interface_type = 0;
+	int addr_offset = -1;
+
+	interface_type = rtw_get_intf_type(adapter);
+
+	switch (rtw_get_chip_type(adapter)) {
+#ifdef CONFIG_RTL8723B
+	case RTL8723B:
+		if (interface_type == RTW_USB)
+			addr_offset = EEPROM_MAC_ADDR_8723BU;
+		else if (interface_type == RTW_SDIO)
+			addr_offset = EEPROM_MAC_ADDR_8723BS;
+		else if (interface_type == RTW_PCIE)
+			addr_offset = EEPROM_MAC_ADDR_8723BE;
+		break;
+#endif
+#ifdef CONFIG_RTL8703B
+	case RTL8703B:
+		if (interface_type == RTW_USB)
+			addr_offset = EEPROM_MAC_ADDR_8703BU;
+		else if (interface_type == RTW_SDIO)
+			addr_offset = EEPROM_MAC_ADDR_8703BS;
+	break;
+#endif
+#ifdef CONFIG_RTL8188E
+	case RTL8188E:
+		if (interface_type == RTW_USB)
+			addr_offset = EEPROM_MAC_ADDR_88EU;
+		else if (interface_type == RTW_SDIO)
+			addr_offset = EEPROM_MAC_ADDR_88ES;
+		else if (interface_type == RTW_PCIE)
+			addr_offset = EEPROM_MAC_ADDR_88EE;
+		break;
+#endif
+#ifdef CONFIG_RTL8188F
+	case RTL8188F:
+		if (interface_type == RTW_USB)
+			addr_offset = EEPROM_MAC_ADDR_8188FU;
+		else if (interface_type == RTW_SDIO)
+			addr_offset = EEPROM_MAC_ADDR_8188FS;
+		break;
+#endif
+#ifdef CONFIG_RTL8812A
+	case RTL8812:
+		if (interface_type == RTW_USB)
+			addr_offset = EEPROM_MAC_ADDR_8812AU;
+		else if (interface_type == RTW_PCIE)
+			addr_offset = EEPROM_MAC_ADDR_8812AE;
+		break;
+#endif
+#ifdef CONFIG_RTL8821A
+	case RTL8821:
+		if (interface_type == RTW_USB)
+			addr_offset = EEPROM_MAC_ADDR_8821AU;
+		else if (interface_type == RTW_SDIO)
+			addr_offset = EEPROM_MAC_ADDR_8821AS;
+		else if (interface_type == RTW_PCIE)
+			addr_offset = EEPROM_MAC_ADDR_8821AE;
+		break;
+#endif
+#ifdef CONFIG_RTL8192E
+	case RTL8192E:
+		if (interface_type == RTW_USB)
+			addr_offset = EEPROM_MAC_ADDR_8192EU;
+		else if (interface_type == RTW_SDIO)
+			addr_offset = EEPROM_MAC_ADDR_8192ES;
+		else if (interface_type == RTW_PCIE)
+			addr_offset = EEPROM_MAC_ADDR_8192EE;
+		break;
+#endif
+#ifdef CONFIG_RTL8814A
+	case RTL8814A:
+		if (interface_type == RTW_USB)
+			addr_offset = EEPROM_MAC_ADDR_8814AU;
+		else if (interface_type == RTW_PCIE)
+			addr_offset = EEPROM_MAC_ADDR_8814AE;
+		break;
+#endif
+	}
+
+	if (addr_offset == -1) {
+		DBG_871X_LEVEL(_drv_err_, "%s: unknown combination - chip_type:%u, interface:%u\n"
+			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
+	}
+
+	return addr_offset;
+}
+
+int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
+{
+	int ret = _FAIL;
+	int addr_offset;
+
+	addr_offset = hal_efuse_macaddr_offset(padapter);
+	if (addr_offset == -1)
+		goto exit;
+
+	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
+
+exit:
+	return ret;
+}
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+	u32 ret;
+
+	ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data);
+	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
+
+	return ret;
+}
+
+u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+	u32 ret = _FAIL;
+
+	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
+		&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
+	) {
+		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
+		ret = _SUCCESS;
+	} else {
+		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
+	}
+
+	return ret;
+}
+#endif /* CONFIG_EFUSE_CONFIG_FILE */
+
+int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	u8 addr[ETH_ALEN];
+	int addr_offset = hal_efuse_macaddr_offset(adapter);
+	u8 *hw_addr = NULL;
+	int ret = _SUCCESS;
+
+	if (autoload_fail)
+		goto bypass_hw_pg;
+
+	if (addr_offset != -1)
+		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+	/* if the hw_addr is written by efuse file, set to NULL */
+	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
+		hw_addr = NULL;
+#endif
+
+	if (!hw_addr) {
+		/* try getting hw pg data */
+		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
+			hw_addr = addr;
+	}
+
+	/* check hw pg data */
+	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
+		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
+		goto exit;
+	}
+	
+bypass_hw_pg:
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+	/* check wifi mac file */
+	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
+		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
+		goto exit;
+	}
+#endif
+
+	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
+	ret = _FAIL;
+
+exit:
+	return ret;
+}
+
+#ifdef CONFIG_RF_GAIN_OFFSET
+u32 Array_kfreemap[] = { 
+0x08,0xe,
+0x06,0xc,
+0x04,0xa,
+0x02,0x8,
+0x00,0x6,
+0x03,0x4,
+0x05,0x2,
+0x07,0x0,
+0x09,0x0,
+0x0c,0x0,
+};
+
+void rtw_bb_rf_gain_offset(_adapter *padapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	struct registry_priv  *registry_par = &padapter->registrypriv;
+	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
+	u8		value = pHalData->EEPROMRFGainOffset;
+	u8		tmp = 0x3e;
+	u32		res, i = 0;
+	u4Byte		ArrayLen	= sizeof(Array_kfreemap)/sizeof(u32);
+	pu4Byte		Array	= Array_kfreemap;
+	u4Byte		v1 = 0, v2 = 0, GainValue = 0, target = 0;
+
+	if (registry_par->RegRfKFreeEnable == 2) {
+		DBG_871X("Registry kfree default force disable.\n");
+		return;
+	}
+
+#if defined(CONFIG_RTL8723B)
+	if (value & BIT4 || (registry_par->RegRfKFreeEnable == 1)) {
+		DBG_871X("Offset RF Gain.\n");
+		DBG_871X("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n",pHalData->EEPROMRFGainVal);
+		
+		if(pHalData->EEPROMRFGainVal != 0xff){
+
+			if(pHalData->ant_path == ODM_RF_PATH_A) {
+				GainValue=(pHalData->EEPROMRFGainVal & 0x0f);
+				
+			} else {
+				GainValue=(pHalData->EEPROMRFGainVal & 0xf0)>>4;
+			}
+			DBG_871X("Ant PATH_%d GainValue Offset = 0x%x\n",(pHalData->ant_path == ODM_RF_PATH_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B),GainValue);
+			
+			for (i = 0; i < ArrayLen; i += 2 )
+			{
+				//DBG_871X("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x \n",i,Array[i],Array[i]+1);
+				v1 = Array[i];
+				v2 = Array[i+1];
+				 if ( v1 == GainValue ) {
+						DBG_871X("Offset RF Gain. got v1 =0x%x ,v2 =0x%x \n",v1,v2);
+						target=v2;
+						break;
+				 }
+			}	 
+			DBG_871X("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n",pHalData->EEPROMRFGainVal,target);
+
+			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
+			DBG_871X("Offset RF Gain. before reg 0x7f=0x%08x\n",res);
+			PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target);
+			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
+
+			DBG_871X("Offset RF Gain. After reg 0x7f=0x%08x\n",res);
+			
+		}else {
+
+			DBG_871X("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n",pHalData->EEPROMRFGainVal);
+		}
+	} else {
+		DBG_871X("Using the default RF gain.\n");
+	}
+
+#elif defined(CONFIG_RTL8188E)
+	if (value & BIT4 || (registry_par->RegRfKFreeEnable == 1)) {
+		DBG_871X("8188ES Offset RF Gain.\n");
+		DBG_871X("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
+				pHalData->EEPROMRFGainVal);
+
+		if (pHalData->EEPROMRFGainVal != 0xff) {
+			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
+					REG_RF_BB_GAIN_OFFSET, 0xffffffff);
+
+			DBG_871X("Offset RF Gain. reg 0x55=0x%x\n",res);
+			res &= 0xfff87fff;
+
+			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
+			DBG_871X("Offset RF Gain. res=0x%x\n",res);
+
+			rtw_hal_write_rfreg(padapter, RF_PATH_A,
+					REG_RF_BB_GAIN_OFFSET,
+					RF_GAIN_OFFSET_MASK, res);
+		} else {
+			DBG_871X("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
+					pHalData->EEPROMRFGainVal);
+		}
+	} else {
+		DBG_871X("Using the default RF gain.\n");
+	}
+#else
+	/* TODO: call this when channel switch */
+	if (kfree_data->flag & KFREE_FLAG_ON)
+		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
+#endif
+	
+}
+#endif //CONFIG_RF_GAIN_OFFSET
+
+bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
+{
+#ifdef CONFIG_RF_GAIN_OFFSET
+	int i, j;
+
+	for (i = 0; i < BB_GAIN_NUM; i++)
+		for (j = 0; j < RF_PATH_MAX; j++)
+			if (data->bb_gain[i][j] != 0)
+				return 0;
+#endif
+	return 1;
+}
+
+#ifdef CONFIG_USB_RX_AGGREGATION	
+void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	if(cur_wireless_mode < WIRELESS_11_24N 
+		&& cur_wireless_mode > 0) //ABG mode
+	{
+#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
+		u32 remainder = 0;
+		u8 quotient = 0;
+
+		remainder = MAX_RECVBUF_SZ % (4*1024); 
+		quotient = (u8)(MAX_RECVBUF_SZ >> 12); 
+		
+		if (quotient > 5) {
+			pHalData->RegAcUsbDmaSize = 0x6;
+			pHalData->RegAcUsbDmaTime = 0x10;
+		} else {
+			if (remainder >= 2048) {
+				pHalData->RegAcUsbDmaSize = quotient;
+				pHalData->RegAcUsbDmaTime = 0x10;
+			} else {
+				pHalData->RegAcUsbDmaSize = (quotient-1);
+				pHalData->RegAcUsbDmaTime = 0x10;
+			}
+		}
+#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
+		if(0x6 != pHalData->RegAcUsbDmaSize || 0x10 !=pHalData->RegAcUsbDmaTime)
+		{
+			pHalData->RegAcUsbDmaSize = 0x6;
+			pHalData->RegAcUsbDmaTime = 0x10;
+			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
+				pHalData->RegAcUsbDmaSize | (pHalData->RegAcUsbDmaTime<<8));
+		}
+#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
+					
+	}
+	else if(cur_wireless_mode >= WIRELESS_11_24N
+			&& cur_wireless_mode <= WIRELESS_MODE_MAX)//N AC mode
+	{
+#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
+		u32 remainder = 0;
+		u8 quotient = 0;
+
+		remainder = MAX_RECVBUF_SZ % (4*1024); 
+		quotient = (u8)(MAX_RECVBUF_SZ >> 12); 
+		
+		if (quotient > 5) {
+			pHalData->RegAcUsbDmaSize = 0x5;
+			pHalData->RegAcUsbDmaTime = 0x20;
+		} else {
+			if (remainder >= 2048) {
+				pHalData->RegAcUsbDmaSize = quotient;
+				pHalData->RegAcUsbDmaTime = 0x10;
+			} else {
+				pHalData->RegAcUsbDmaSize = (quotient-1);
+				pHalData->RegAcUsbDmaTime = 0x10;
+			}
+		}
+#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
+		if(0x5 != pHalData->RegAcUsbDmaSize || 0x20 !=pHalData->RegAcUsbDmaTime)
+		{
+			pHalData->RegAcUsbDmaSize = 0x5;
+			pHalData->RegAcUsbDmaTime = 0x20;
+			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
+				pHalData->RegAcUsbDmaSize | (pHalData->RegAcUsbDmaTime<<8));
+		}
+#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
+
+	}
+	else
+	{
+		/* DBG_871X("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
+	}
+}
+#endif //CONFIG_USB_RX_AGGREGATION
+
+//To avoid RX affect TX throughput
+void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
+{
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
+	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
+	struct mlme_ext_priv	*pmlmeextpriv = &(padapter->mlmeextpriv);
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u8 cur_wireless_mode = pmlmeextpriv->cur_wireless_mode;
+#ifdef CONFIG_CONCURRENT_MODE
+	struct mlme_ext_priv	*pbuddymlmeextpriv = &(padapter->pbuddy_adapter->mlmeextpriv);
+#endif //CONFIG_CONCURRENT_MODE
+
+#ifdef CONFIG_USB_RX_AGGREGATION	
+	if(IS_HARDWARE_TYPE_8821U(padapter) )//|| IS_HARDWARE_TYPE_8192EU(padapter))
+	{
+		//This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB
+		if((pHalData->UsbRxAggMode == USB_RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+		{
+			if(pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
+				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
+			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
+				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);			
+			else
+				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,0x2005); //dmc agg th 20K
+			
+			//DBG_871X("TX_TP=%u, RX_TP=%u \n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp);
+		}
+	}
+	else if(IS_HARDWARE_TYPE_8812(padapter))
+	{
+#ifdef CONFIG_CONCURRENT_MODE
+		if(rtw_linked_check(padapter) == _TRUE && rtw_linked_check(padapter->pbuddy_adapter) == _TRUE)
+		{
+			if(pbuddymlmeextpriv->cur_wireless_mode >= pmlmeextpriv->cur_wireless_mode)
+				cur_wireless_mode = pbuddymlmeextpriv->cur_wireless_mode;
+			else
+				cur_wireless_mode = pmlmeextpriv->cur_wireless_mode;
+
+			rtw_set_usb_agg_by_mode(padapter,cur_wireless_mode);
+		}
+		else if (rtw_linked_check(padapter) == _TRUE && rtw_linked_check(padapter->pbuddy_adapter) == _FALSE)
+		{
+			rtw_set_usb_agg_by_mode(padapter,cur_wireless_mode);
+		}
+#else //!CONFIG_CONCURRENT_MODE
+		rtw_set_usb_agg_by_mode(padapter,cur_wireless_mode);
+#endif //CONFIG_CONCURRENT_MODE
+	}
+#endif
+}
+
+//bus-agg check for SoftAP mode
+inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter,u8 pre_qsel,u8 next_qsel)
+{
+	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	u8 chk_rst = _SUCCESS;
+	
+	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
+		return chk_rst;
+
+	//if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) 
+	//	return chk_rst;
+	
+	if(	((pre_qsel == QSLT_HIGH)||((next_qsel== QSLT_HIGH))) 
+			&& (pre_qsel != next_qsel )){
+			//DBG_871X("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n",
+			//	pre_qsel,next_qsel);
+			chk_rst = _FAIL;
+		}
+	return chk_rst;
+}
+
+/*
+ * Description:
+ * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
+ * contant.
+ *
+ * Input:
+ * adapter: adapter pointer.
+ * page_num: The max. page number that user want to dump. 
+ * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
+ */
+void dump_TX_FIFO(_adapter* padapter, u8 page_num, u16 page_size){
+
+	int i;
+	u8 val = 0;
+	u8 base = 0;
+	u32 addr = 0;
+	u32 count = (page_size / 8);
+
+	if (page_num <= 0) {
+		DBG_871X("!!%s: incorrect input page_num paramter!\n", __func__);
+		return;
+	}
+
+	if (page_size < 128 || page_size > 512) {
+		DBG_871X("!!%s: incorrect input page_size paramter!\n", __func__);
+		return;
+	}
+
+	DBG_871X("+%s+\n", __func__);
+	val = rtw_read8(padapter, 0x106);
+	rtw_write8(padapter, 0x106, 0x69);
+	DBG_871X("0x106: 0x%02x\n", val);
+	base = rtw_read8(padapter, 0x209);
+	DBG_871X("0x209: 0x%02x\n", base);
+
+	addr = ((base) * page_size)/8;
+	for (i = 0 ; i < page_num * count ; i+=2) {
+		rtw_write32(padapter, 0x140, addr + i);
+		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
+		rtw_write32(padapter, 0x140, addr + i + 1);
+		printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
+	}
+}
+
+#ifdef CONFIG_GPIO_API
+u8 rtw_hal_get_gpio(_adapter* adapter, u8 gpio_num)
+{
+	u8 value;
+	u8 direction;	
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+
+	rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+	DBG_871X("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
+	LeaveAllPowerSaveModeDirect(adapter);
+
+	/* Read GPIO Direction */
+	direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
+
+	/* According the direction to read register value */
+	if( direction )
+		value =  (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1)& BIT(gpio_num)) >> gpio_num;
+	else
+		value =  (rtw_read8(adapter, REG_GPIO_PIN_CTRL)& BIT(gpio_num)) >> gpio_num;
+
+	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+	DBG_871X("%s direction=%d value=%d\n",__FUNCTION__,direction,value);
+
+	return value;
+}
+
+int  rtw_hal_set_gpio_output_value(_adapter* adapter, u8 gpio_num, bool isHigh)
+{
+	u8 direction = 0;
+	u8 res = -1;
+	if (IS_HARDWARE_TYPE_8188E(adapter)){
+		/* Check GPIO is 4~7 */
+		if( gpio_num > 7 || gpio_num < 4)
+		{
+			DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__);
+			return -1;
+		}
+	}	
+	
+	rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+	LeaveAllPowerSaveModeDirect(adapter);
+
+	/* Read GPIO direction */
+	direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
+
+	/* If GPIO is output direction, setting value. */
+	if( direction )
+	{
+		if(isHigh)
+			rtw_write8(adapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1) | BIT(gpio_num));
+		else
+			rtw_write8(adapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(gpio_num));
+
+		DBG_871X("%s Set gpio %x[%d]=%d\n",__FUNCTION__,REG_GPIO_PIN_CTRL+1,gpio_num,isHigh );
+		res = 0;
+	}
+	else
+	{
+		DBG_871X("%s The gpio is input,not be set!\n",__FUNCTION__);
+		res = -1;
+	}
+
+	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+	return res;
+}
+
+int rtw_hal_config_gpio(_adapter* adapter, u8 gpio_num, bool isOutput)
+{
+	if (IS_HARDWARE_TYPE_8188E(adapter)){
+		if( gpio_num > 7 || gpio_num < 4)
+		{
+			DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__);
+			return -1;
+		}
+	}	
+
+	DBG_871X("%s gpio_num =%d direction=%d\n",__FUNCTION__,gpio_num,isOutput);
+
+	rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+	LeaveAllPowerSaveModeDirect(adapter);
+
+	if( isOutput )
+	{
+		rtw_write8(adapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) | BIT(gpio_num));
+	}
+	else
+	{
+		rtw_write8(adapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(gpio_num));
+	}
+
+	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+
+	return 0;
+}
+int rtw_hal_register_gpio_interrupt(_adapter* adapter, int gpio_num, void(*callback)(u8 level))
+{
+	u8 value;
+	u8 direction;
+	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
+
+	if (IS_HARDWARE_TYPE_8188E(adapter)){	
+		if(gpio_num > 7 || gpio_num < 4)
+		{
+			DBG_871X_LEVEL(_drv_always_, "%s The gpio number does not included 4~7.\n",__FUNCTION__);
+			return -1;
+		}
+	}
+
+	rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+	LeaveAllPowerSaveModeDirect(adapter);
+
+	/* Read GPIO direction */
+	direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
+	if(direction){
+		DBG_871X_LEVEL(_drv_always_, "%s Can't register output gpio as interrupt.\n",__FUNCTION__);
+		return -1;
+	}
+
+	/* Config GPIO Mode */
+	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));	
+
+	/* Register GPIO interrupt handler*/
+	adapter->gpiointpriv.callback[gpio_num] = callback;
+	
+	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
+	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
+	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2)^value;
+	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
+	
+	/* Enable GPIO interrupt */
+	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
+	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
+
+	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
+	
+	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+
+	return 0;
+}
+int rtw_hal_disable_gpio_interrupt(_adapter* adapter, int gpio_num)
+{
+	u8 value;
+	u8 direction;
+	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
+
+	if (IS_HARDWARE_TYPE_8188E(adapter)){
+		if(gpio_num > 7 || gpio_num < 4)
+		{
+			DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__);
+			return -1;
+		}
+	}
+
+	rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+	LeaveAllPowerSaveModeDirect(adapter);
+
+	/* Config GPIO Mode */
+	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) &~ BIT(gpio_num));	
+
+	/* Unregister GPIO interrupt handler*/
+	adapter->gpiointpriv.callback[gpio_num] = NULL;
+
+	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
+	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) &~ BIT(gpio_num);
+	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
+	
+	/* Disable GPIO interrupt */
+	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) &~ BIT(gpio_num);
+	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
+
+	if(!adapter->gpiointpriv.interrupt_enable_mask)
+		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
+	
+	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+
+	return 0;
+}
+#endif
+
+void rtw_dump_mac_rx_counters(_adapter* padapter,struct dbg_rx_counter *rx_counter)
+{
+	u32	mac_cck_ok=0, mac_ofdm_ok=0, mac_ht_ok=0, mac_vht_ok=0;
+	u32	mac_cck_err=0, mac_ofdm_err=0, mac_ht_err=0, mac_vht_err=0;
+	u32	mac_cck_fa=0, mac_ofdm_fa=0, mac_ht_fa=0;
+	u32	DropPacket=0;
+	
+	if(!rx_counter){
+		rtw_warn_on(1);
+		return;
+	}
+
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x3);
+	mac_cck_ok	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	  
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x0);
+	mac_ofdm_ok	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	 
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x6);
+	mac_ht_ok	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	
+	mac_vht_ok	= 0;	
+	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
+		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x0);
+		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x1);
+		mac_vht_ok	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	 
+	}	
+		
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x4);
+	mac_cck_err	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x1);
+	mac_ofdm_err	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x7);
+	mac_ht_err	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]		
+	mac_vht_err	= 0;
+	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
+		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x1);
+		PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x1);
+		mac_vht_err	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	 
+	}
+
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x5);
+	mac_cck_fa	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x2);
+	mac_ofdm_fa	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]	
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x9);
+	mac_ht_fa	= PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0]		
+	
+	//Mac_DropPacket
+	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT)& 0x0FFFFFFF)| Mac_DropPacket);
+	DropPacket = rtw_read32(padapter, REG_RXERR_RPT)& 0x0000FFFF;
+
+	rx_counter->rx_pkt_ok = mac_cck_ok+mac_ofdm_ok+mac_ht_ok+mac_vht_ok;
+	rx_counter->rx_pkt_crc_error = mac_cck_err+mac_ofdm_err+mac_ht_err+mac_vht_err;
+	rx_counter->rx_cck_fa = mac_cck_fa;
+	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
+	rx_counter->rx_ht_fa = mac_ht_fa;
+	rx_counter->rx_pkt_drop = DropPacket;
+}
+void rtw_reset_mac_rx_counters(_adapter* padapter)
+{
+
+	if (IS_HARDWARE_TYPE_8703B(padapter) || IS_HARDWARE_TYPE_8188F(padapter))
+		PHY_SetMacReg(padapter, 0x608, BIT19, 0x1); /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/	
+
+	//reset mac counter
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT27, 0x1); 
+	PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT27, 0x0);
+}
+
+void rtw_dump_phy_rx_counters(_adapter* padapter,struct dbg_rx_counter *rx_counter)
+{
+	u32 cckok=0,cckcrc=0,ofdmok=0,ofdmcrc=0,htok=0,htcrc=0,OFDM_FA=0,CCK_FA=0,vht_ok=0,vht_err=0;
+	if(!rx_counter){
+		rtw_warn_on(1);
+		return;
+	}
+	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)){
+		cckok	= PHY_QueryBBReg(padapter, 0xF04, 0x3FFF);	     // [13:0] 
+		ofdmok	= PHY_QueryBBReg(padapter, 0xF14, 0x3FFF);	     // [13:0] 
+		htok		= PHY_QueryBBReg(padapter, 0xF10, 0x3FFF);     // [13:0]
+		vht_ok	= PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF);     // [13:0]
+		cckcrc	= PHY_QueryBBReg(padapter, 0xF04, 0x3FFF0000); // [29:16]	
+		ofdmcrc	= PHY_QueryBBReg(padapter, 0xF14, 0x3FFF0000); // [29:16]
+		htcrc	= PHY_QueryBBReg(padapter, 0xF10, 0x3FFF0000); // [29:16]
+		vht_err	= PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF0000); // [29:16]
+		CCK_FA	= PHY_QueryBBReg(padapter, 0xA5C, bMaskLWord);
+		OFDM_FA	= PHY_QueryBBReg(padapter, 0xF48, bMaskLWord);
+	} 
+	else
+	{
+		cckok	= PHY_QueryBBReg(padapter, 0xF88, bMaskDWord);
+		ofdmok	= PHY_QueryBBReg(padapter, 0xF94, bMaskLWord);
+		htok		= PHY_QueryBBReg(padapter, 0xF90, bMaskLWord);
+		vht_ok	= 0;
+		cckcrc	= PHY_QueryBBReg(padapter, 0xF84, bMaskDWord);
+		ofdmcrc	= PHY_QueryBBReg(padapter, 0xF94, bMaskHWord);
+		htcrc	= PHY_QueryBBReg(padapter, 0xF90, bMaskHWord);
+		vht_err	= 0;
+		OFDM_FA = PHY_QueryBBReg(padapter, 0xCF0, bMaskLWord) + PHY_QueryBBReg(padapter, 0xCF2, bMaskLWord) +
+			PHY_QueryBBReg(padapter, 0xDA2, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA4, bMaskLWord) +
+			PHY_QueryBBReg(padapter, 0xDA6, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA8, bMaskLWord);
+	
+		CCK_FA=(rtw_read8(padapter, 0xA5B )<<8 ) | (rtw_read8(padapter, 0xA5C));
+	}
+	
+	rx_counter->rx_pkt_ok = cckok+ofdmok+htok+vht_ok;
+	rx_counter->rx_pkt_crc_error = cckcrc+ofdmcrc+htcrc+vht_err;
+	rx_counter->rx_ofdm_fa = OFDM_FA;
+	rx_counter->rx_cck_fa = CCK_FA;
+	
+}
+
+void rtw_reset_phy_rx_counters(_adapter* padapter)
+{
+	//reset phy counter
+	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
+	{
+		PHY_SetBBReg(padapter, 0xB58, BIT0, 0x1);
+		PHY_SetBBReg(padapter, 0xB58, BIT0, 0x0);
+
+		PHY_SetBBReg(padapter, 0x9A4, BIT17, 0x1);//reset  OFDA FA counter
+		PHY_SetBBReg(padapter, 0x9A4, BIT17, 0x0);
+			
+		PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x0);//reset  CCK FA counter
+		PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x1);
+	}
+	else
+	{
+		PHY_SetBBReg(padapter, 0xF14, BIT16, 0x1);
+		rtw_msleep_os(10);
+		PHY_SetBBReg(padapter, 0xF14, BIT16, 0x0);
+		
+		PHY_SetBBReg(padapter, 0xD00, BIT27, 0x1);//reset  OFDA FA counter
+		PHY_SetBBReg(padapter, 0xC0C, BIT31, 0x1);//reset  OFDA FA counter
+		PHY_SetBBReg(padapter, 0xD00, BIT27, 0x0);
+		PHY_SetBBReg(padapter, 0xC0C, BIT31, 0x0);
+			
+		PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x0);//reset  CCK FA counter
+		PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x1);
+	}
+}
+#ifdef DBG_RX_COUNTER_DUMP
+void rtw_dump_drv_rx_counters(_adapter* padapter,struct dbg_rx_counter *rx_counter)
+{
+	struct recv_priv *precvpriv = &padapter->recvpriv;
+	if(!rx_counter){
+		rtw_warn_on(1);
+		return;
+	}
+	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
+	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
+	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;	
+}
+void rtw_reset_drv_rx_counters(_adapter* padapter)
+{
+	struct recv_priv *precvpriv = &padapter->recvpriv;
+	padapter->drv_rx_cnt_ok = 0;
+	padapter->drv_rx_cnt_crcerror = 0;
+	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
+}
+void rtw_dump_phy_rxcnts_preprocess(_adapter* padapter,u8 rx_cnt_mode)
+{
+	u8 initialgain;
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+	DM_ODM_T *odm = &(hal_data->odmpriv);
+	DIG_T	*pDigTable = &odm->DM_DigTable;
+	
+	if((!(padapter->dump_rx_cnt_mode& DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER))
+	{
+		initialgain = pDigTable->CurIGValue;
+		DBG_871X("%s CurIGValue:0x%02x\n",__FUNCTION__,initialgain);
+		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
+		/*disable dynamic functions, such as high power, DIG*/
+		rtw_phydm_ability_backup(padapter);
+		rtw_phydm_func_clr(padapter, (ODM_BB_DIG|ODM_BB_FA_CNT));
+	}
+	else if((padapter->dump_rx_cnt_mode& DUMP_PHY_RX_COUNTER) &&(!(rx_cnt_mode & DUMP_PHY_RX_COUNTER )))
+	{
+		//turn on phy-dynamic functions
+		rtw_phydm_ability_restore(padapter);
+		initialgain = 0xff; //restore RX GAIN
+		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
+		
+	}
+}
+	
+void rtw_dump_rx_counters(_adapter* padapter)
+{
+	struct dbg_rx_counter rx_counter;
+
+	if( padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER ){
+		_rtw_memset(&rx_counter,0,sizeof(struct dbg_rx_counter));
+		rtw_dump_drv_rx_counters(padapter,&rx_counter);
+		DBG_871X( "Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
+					rx_counter.rx_pkt_ok,rx_counter.rx_pkt_crc_error,rx_counter.rx_pkt_drop);		
+		rtw_reset_drv_rx_counters(padapter);		
+	}
+		
+	if( padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER ){
+		_rtw_memset(&rx_counter,0,sizeof(struct dbg_rx_counter));
+		rtw_dump_mac_rx_counters(padapter,&rx_counter);
+		DBG_871X( "Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
+					rx_counter.rx_pkt_ok,rx_counter.rx_pkt_crc_error,
+					rx_counter.rx_cck_fa+rx_counter.rx_ofdm_fa+rx_counter.rx_ht_fa,
+					rx_counter.rx_pkt_drop);			
+		rtw_reset_mac_rx_counters(padapter);
+	}
+
+	if(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER ){		
+		_rtw_memset(&rx_counter,0,sizeof(struct dbg_rx_counter));		
+		rtw_dump_phy_rx_counters(padapter,&rx_counter);
+		//DBG_871X("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa);
+		//DBG_871X("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa);
+		DBG_871X("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n",rx_counter.rx_pkt_ok,rx_counter.rx_pkt_crc_error,
+		rx_counter.rx_ofdm_fa+rx_counter.rx_cck_fa);
+		rtw_reset_phy_rx_counters(padapter);	
+	}
+}
+#endif
+void rtw_get_noise(_adapter* padapter)
+{
+#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
+	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
+	struct noise_info info;
+	if(rtw_linked_check(padapter)){
+		info.bPauseDIG = _TRUE;
+		info.IGIValue = 0x1e;
+		info.max_time = 100;//ms
+		info.chan = pmlmeext->cur_channel ;//rtw_get_oper_ch(padapter);
+		rtw_ps_deny(padapter, PS_DENY_IOCTL);
+		LeaveAllPowerSaveModeDirect(padapter);
+
+		rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&info, _FALSE);	
+		//ODM_InbandNoise_Monitor(podmpriv,_TRUE,0x20,100);
+		rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
+		rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(info.chan), &(padapter->recvpriv.noise));	
+		#ifdef DBG_NOISE_MONITOR
+		DBG_871X("chan:%d,noise_level:%d\n",info.chan,padapter->recvpriv.noise);
+		#endif
+	}
+#endif		
+
+}
+
+#ifdef CONFIG_FW_C2H_DEBUG
+
+/*	C2H RX package original is 128.
+if enable CONFIG_FW_C2H_DEBUG, it should increase to 256.
+ C2H FW debug message:
+ without aggregate:
+ {C2H_CmdID,Seq,SubID,Len,Content[0~n]}
+ Content[0~n]={'a','b','c',...,'z','\n'}
+ with aggregate:
+ {C2H_CmdID,Seq,SubID,Len,Content[0~n]}
+ Content[0~n]={'a','b','c',...,'z','\n',Extend C2H pkt 2...}
+ Extend C2H pkt 2={C2H CmdID,Seq,SubID,Len,Content = {'a','b','c',...,'z','\n'}}
+ Author: Isaac	*/
+
+void Debug_FwC2H(PADAPTER padapter, u8 *pdata, u8 len)
+{
+	int i = 0;
+	int cnt = 0, total_length = 0;
+	u8 buf[128] = {0};
+	u8 more_data = _FALSE;
+	u8 *nextdata = NULL;
+	u8 test = 0;
+
+	u8 data_len;
+	u8 seq_no;
+
+	nextdata = pdata;
+	do {
+		data_len = *(nextdata + 1);
+		seq_no = *(nextdata + 2);
+
+		for (i = 0 ; i < data_len - 2 ; i++) {
+			cnt += sprintf((buf+cnt), "%c", nextdata[3 + i]);
+
+			if (nextdata[3 + i] == 0x0a && nextdata[4 + i] == 0xff)
+				more_data = _TRUE;
+			else if (nextdata[3 + i] == 0x0a && nextdata[4 + i] != 0xff)
+				more_data = _FALSE;
+		}
+
+		DBG_871X("[RTKFW, SEQ=%d]: %s", seq_no, buf);
+		data_len += 3;
+		total_length += data_len;
+
+		if (more_data == _TRUE) {
+			_rtw_memset(buf, '\0', 128);
+			cnt = 0;
+			nextdata = (pdata + total_length);
+		}
+	} while (more_data == _TRUE);
+}
+#endif /*CONFIG_FW_C2H_DEBUG*/
+void update_IOT_info(_adapter *padapter)
+{
+	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	
+	switch (pmlmeinfo->assoc_AP_vendor)
+	{
+		case HT_IOT_PEER_MARVELL:
+			pmlmeinfo->turboMode_cts2self = 1;
+			pmlmeinfo->turboMode_rtsen = 0;
+			break;
+		
+		case HT_IOT_PEER_RALINK:
+			pmlmeinfo->turboMode_cts2self = 0;
+			pmlmeinfo->turboMode_rtsen = 1;
+			//disable high power			
+			rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
+			break;
+		case HT_IOT_PEER_REALTEK:
+			//rtw_write16(padapter, 0x4cc, 0xffff);
+			//rtw_write16(padapter, 0x546, 0x01c0);
+			//disable high power			
+			rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
+			break;
+		default:
+			pmlmeinfo->turboMode_cts2self = 0;
+			pmlmeinfo->turboMode_rtsen = 1;
+			break;	
+	}
+	
+}
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM
+void rtw_acs_start(_adapter *padapter, bool bStart)
+{	
+	if (_TRUE == bStart) {
+		ACS_OP acs_op = ACS_INIT;
+		
+		rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
+		rtw_set_acs_channel(padapter, 0);
+		SET_ACS_STATE(padapter, ACS_ENABLE);		
+	} else {		
+		SET_ACS_STATE(padapter, ACS_DISABLE);
+		#ifdef DBG_AUTO_CHNL_SEL_NHM
+		if (1) {
+			u8 best_24g_ch = 0;
+			u8 best_5g_ch = 0;
+			
+			rtw_hal_get_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &(best_24g_ch), &(best_5g_ch));
+			DBG_871X("[ACS-"ADPT_FMT"] Best 2.4G CH:%u\n", ADPT_ARG(padapter), best_24g_ch);
+			DBG_871X("[ACS-"ADPT_FMT"] Best 5G CH:%u\n", ADPT_ARG(padapter), best_5g_ch);
+		}
+		#endif
+	}
+}
+#endif
+
+/* TODO: merge with phydm, see odm_SetCrystalCap() */
+void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap)
+{
+	crystal_cap = crystal_cap & 0x3F;
+
+	switch (rtw_get_chip_type(adapter)) {
+#if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F)
+	case RTL8188E:
+	case RTL8188F:
+		/* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
+		PHY_SetBBReg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6)));
+		break;
+#endif
+#if defined(CONFIG_RTL8812A)
+	case RTL8812:
+		/* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */
+		PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
+		break;
+#endif
+#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8192E)
+	case RTL8723B:
+	case RTL8703B:
+	case RTL8821:
+	case RTL8192E:
+		/* write 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
+		PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6)));
+		break;
+#endif
+#if defined(CONFIG_RTL8814A)
+	case RTL8814A:
+		/* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap*/
+		PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6)));
+		break;
+#endif
+#if defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B)
+	case RTL8821B:
+	case RTL8822B:
+		/* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
+		crystal_cap = crystal_cap & 0x3F;
+		PHY_SetBBReg(adapter, REG_AFE_XTAL_CTRL, 0x7E000000, crystal_cap);
+		PHY_SetBBReg(adapter, REG_AFE_PLL_CTRL, 0x7E, crystal_cap);
+		break;
+#endif
+	default:
+		rtw_warn_on(1);
+	}
+}
+
+int hal_spec_init(_adapter *adapter)
+{
+	u8 interface_type = 0;
+	int ret = _SUCCESS;
+
+	interface_type = rtw_get_intf_type(adapter);
+
+	switch (rtw_get_chip_type(adapter)) {
+#ifdef CONFIG_RTL8723B
+	case RTL8723B:
+		init_hal_spec_8723b(adapter);
+		break;
+#endif
+#ifdef CONFIG_RTL8703B
+	case RTL8703B:
+		init_hal_spec_8703b(adapter);
+		break;
+#endif
+#ifdef CONFIG_RTL8188E
+	case RTL8188E:
+		init_hal_spec_8188e(adapter);
+		break;
+#endif
+#ifdef CONFIG_RTL8188F
+	case RTL8188F:
+		init_hal_spec_8188f(adapter);
+		break;
+#endif
+#ifdef CONFIG_RTL8812A
+	case RTL8812:
+		init_hal_spec_8812a(adapter);
+		break;
+#endif
+#ifdef CONFIG_RTL8821A
+	case RTL8821:
+		init_hal_spec_8821a(adapter);
+		break;
+#endif
+#ifdef CONFIG_RTL8192E
+	case RTL8192E:
+		init_hal_spec_8192e(adapter);
+		break;
+#endif
+#ifdef CONFIG_RTL8814A
+	case RTL8814A:
+		init_hal_spec_8814a(adapter);
+		break;
+#endif
+	default:
+		DBG_871X_LEVEL(_drv_err_, "%s: unknown chip_type:%u\n"
+			, __func__, rtw_get_chip_type(adapter));
+		ret = _FAIL;
+		break;
+	}
+
+	return ret;
+}
+
+static const char * const _band_cap_str[] = {
+	/* BIT0 */"2G",
+	/* BIT1 */"5G",
+};
+
+static const char * const _bw_cap_str[] = {
+	/* BIT0 */"5M",
+	/* BIT1 */"10M",
+	/* BIT2 */"20M",
+	/* BIT3 */"40M",
+	/* BIT4 */"80M",
+	/* BIT5 */"160M",
+	/* BIT6 */"80_80M",
+};
+
+static const char * const _proto_cap_str[] = {
+	/* BIT0 */"b",
+	/* BIT1 */"g",
+	/* BIT2 */"n",
+	/* BIT3 */"ac",
+};
+
+static const char * const _wl_func_str[] = {
+	/* BIT0 */"P2P",
+	/* BIT1 */"MIRACAST",
+	/* BIT2 */"TDLS",
+	/* BIT3 */"FTM",
+};
+
+void dump_hal_spec(void *sel, _adapter *adapter)
+{
+	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+	int i;
+
+	DBG_871X_SEL_NL(sel, "macid_num:%u\n", hal_spec->macid_num);
+	DBG_871X_SEL_NL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
+	DBG_871X_SEL_NL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
+	DBG_871X_SEL_NL(sel, "nss_num:%u\n", hal_spec->nss_num);
+
+	DBG_871X_SEL_NL(sel, "band_cap:");
+	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
+		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
+			DBG_871X_SEL(sel, "%s ", _band_cap_str[i]);
+	}
+	DBG_871X_SEL(sel, "\n");
+
+	DBG_871X_SEL_NL(sel, "bw_cap:");
+	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
+		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
+			DBG_871X_SEL(sel, "%s ", _bw_cap_str[i]);
+	}
+	DBG_871X_SEL(sel, "\n");
+
+	DBG_871X_SEL_NL(sel, "proto_cap:");
+	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
+		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
+			DBG_871X_SEL(sel, "%s ", _proto_cap_str[i]);
+	}
+	DBG_871X_SEL(sel, "\n");
+
+	DBG_871X_SEL_NL(sel, "wl_func:");
+	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
+		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
+			DBG_871X_SEL(sel, "%s ", _wl_func_str[i]);
+	}
+	DBG_871X_SEL(sel, "\n");
+}
+
+inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
+{
+	return (GET_HAL_SPEC(adapter)->band_cap & cap);
+}
+
+inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
+{
+	return (GET_HAL_SPEC(adapter)->bw_cap & cap);
+}
+
+inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
+{
+	return (GET_HAL_SPEC(adapter)->proto_cap & cap);
+}
+
+inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
+{
+	return (GET_HAL_SPEC(adapter)->wl_func & func);
+}
+
+inline bool hal_is_band_support(_adapter *adapter, u8 band)
+{
+	return (GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band));
+}
+
+inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
+{
+	return (GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw));
+}
+
+inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
+{
+	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
+
+	if (mode == WIRELESS_11B)
+		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
+			return 1;
+
+	if (mode == WIRELESS_11G)
+		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
+			return 1;
+
+	if (mode == WIRELESS_11A)
+		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
+			return 1;
+
+	if (mode == WIRELESS_11_24N)
+		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
+			return 1;
+
+	if (mode == WIRELESS_11_5N)
+		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
+			return 1;
+
+	if (mode == WIRELESS_11AC)
+		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
+			return 1;
+
+	return 0;
+}
+
+/*
+* hal_largest_bw - starting from in_bw, get largest bw supported by HAL
+* @adapter:
+* @in_bw: starting bw, value of CHANNEL_WIDTH
+*
+* Returns: value of CHANNEL_WIDTH
+*/
+u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
+{
+	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
+		if (hal_is_bw_support(adapter, in_bw))
+			break;
+	}
+
+	if (!hal_is_bw_support(adapter, in_bw))
+		rtw_warn_on(1);
+
+	return in_bw;
+}
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com_c2h.h b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com_c2h.h
new file mode 100644
index 000000000..e9760efa8
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com_c2h.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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 __COMMON_C2H_H__
+#define __COMMON_C2H_H__
+
+typedef enum _C2H_EVT {
+	C2H_DBG = 0x00,
+	C2H_LB = 0x01,
+	C2H_TXBF = 0x02,
+	C2H_CCX_TX_RPT = 0x03,
+	C2H_BT_INFO = 0x09,
+	C2H_BT_MP_INFO = 0x0B,
+	C2H_RA_RPT = 0x0C,
+	C2H_RA_PARA_RPT = 0x0E,
+	C2H_FW_SWCHNL = 0x10,
+	C2H_IQK_FINISH = 0x11,
+	C2H_MAILBOX_STATUS = 0x15,
+	C2H_P2P_RPORT = 0x16,
+	C2H_MAC_HIDDEN_RPT = 0x19,
+	C2H_BT_SCOREBOARD_STATUS = 0x20,
+	C2H_EXTEND = 0xff,
+} C2H_EVT;
+
+typedef enum _EXTEND_C2H_EVT {
+	EXTEND_C2H_DBG_PRINT = 0
+} EXTEND_C2H_EVT;
+
+#define MAC_HIDDEN_RPT_LEN 8
+int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len);
+int hal_read_mac_hidden_rpt(_adapter *adapter);
+
+#endif /* __COMMON_C2H_H__ */
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com_phycfg.c b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com_phycfg.c
new file mode 100644
index 000000000..949d36d87
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_com_phycfg.c
@@ -0,0 +1,4440 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#define _HAL_COM_PHYCFG_C_
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+/*
+* rtw_regsty_get_target_tx_power -
+*
+* Return dBm or -1 for undefined
+*/
+s8 rtw_regsty_get_target_tx_power(
+	IN	PADAPTER		Adapter,
+	IN	u8				Band,
+	IN	u8				RfPath,
+	IN	RATE_SECTION	RateSection
+	)
+{
+	struct registry_priv *regsty = adapter_to_regsty(Adapter);
+	s8 value = 0;
+
+	if (RfPath > RF_PATH_D) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath);
+		return -1;
+	}
+
+	if (Band != BAND_ON_2_4G
+		#ifdef CONFIG_IEEE80211_BAND_5GHZ
+		&& Band != BAND_ON_5G
+		#endif
+	) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band);
+		return -1;
+	}
+
+	if (RateSection >= RATE_SECTION_NUM
+		#ifdef CONFIG_IEEE80211_BAND_5GHZ
+		|| (Band == BAND_ON_5G && RateSection == CCK)
+		#endif
+	) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in %sG, RfPath:%d\n", __func__
+			, RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath);
+		return -1;
+	}
+
+	if (Band == BAND_ON_2_4G)
+		value = regsty->target_tx_pwr_2g[RfPath][RateSection];
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+	else /* BAND_ON_5G */
+		value = regsty->target_tx_pwr_5g[RfPath][RateSection - 1];
+#endif
+
+	return value;
+}
+
+bool rtw_regsty_chk_target_tx_power_valid(_adapter *adapter)
+{
+	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	int path, tx_num, band, rs;
+	s8 target;
+
+	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+		if (!hal_is_band_support(adapter, band))
+			continue;
+
+		for (path = 0; path < RF_PATH_MAX; path++) {
+			if (path >= hal_data->NumTotalRFPath)
+				break;
+
+			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+				tx_num = rate_section_to_tx_num(rs);
+				if (tx_num >= hal_spec->nss_num)
+					continue;
+
+				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+					continue;
+
+				if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
+					continue;
+
+				target = rtw_regsty_get_target_tx_power(adapter, band, path, rs);
+				if (target == -1)
+					return _FALSE;
+			}
+		}
+	}
+
+	return _TRUE;
+}
+
+/*
+* PHY_GetTxPowerByRateBase -
+*
+* Return 2 times of dBm
+*/
+u8
+PHY_GetTxPowerByRateBase(
+	IN	PADAPTER		Adapter,
+	IN	u8				Band,
+	IN	u8				RfPath,
+	IN	u8				TxNum,
+	IN	RATE_SECTION	RateSection
+	)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+	u8 value = 0;
+
+	if (RfPath > RF_PATH_D) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath);
+		return 0;
+	}
+
+	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band);
+		return 0;
+	}
+
+	if (RateSection >= RATE_SECTION_NUM
+		|| (Band == BAND_ON_5G && RateSection == CCK)
+	) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in %sG, RfPath:%d, TxNum:%d\n", __func__
+			, RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath, TxNum);
+		return 0;
+	}
+
+	if (Band == BAND_ON_2_4G)
+		value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection];
+	else /* BAND_ON_5G */
+		value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1];
+
+	return value;
+}
+
+VOID
+phy_SetTxPowerByRateBase(
+	IN	PADAPTER		Adapter,
+	IN	u8				Band,
+	IN	u8				RfPath,
+	IN	RATE_SECTION	RateSection,
+	IN	u8				TxNum,
+	IN	u8				Value
+	)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+	
+	if (RfPath > RF_PATH_D) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath);
+		return;
+	}
+
+	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band);
+		return;
+	}
+
+	if (RateSection >= RATE_SECTION_NUM
+		|| (Band == BAND_ON_5G && RateSection == CCK)
+	) {
+		DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in %sG, RfPath:%d, TxNum:%d\n", __func__
+			, RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath, TxNum);
+		return;
+	}
+
+	if (Band == BAND_ON_2_4G)
+		pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection] = Value;
+	else /* BAND_ON_5G */
+		pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1] = Value;
+}
+
+/*
+* phy_get_target_tx_power -
+*
+* Return 2 times of dBm
+*/
+u8 phy_get_target_tx_power(
+	IN	PADAPTER		Adapter,
+	IN	u8				Band,
+	IN	u8				RfPath,
+	IN	RATE_SECTION	RateSection
+	)
+{
+	struct registry_priv *regsty = adapter_to_regsty(Adapter);
+	s16 target_power;
+
+	if (phy_is_tx_power_by_rate_needed(Adapter) == _FALSE && regsty->target_tx_pwr_valid == _TRUE)
+		target_power = 2 * rtw_regsty_get_target_tx_power(Adapter, Band, RfPath, RateSection);
+	else
+		target_power = PHY_GetTxPowerByRateBase(Adapter, Band, RfPath, rate_section_to_tx_num(RateSection), RateSection);
+
+	return target_power;
+}
+
+#ifdef TX_POWER_BY_RATE_OLD
+VOID
+phy_StoreTxPowerByRateBaseOld(	
+	IN	PADAPTER	pAdapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA( pAdapter );
+	u16			rawValue = 0;
+	u8			base = 0;
+	u8			path = 0;
+
+	rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][7] >> 8 ) & 0xFF; 
+	base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
+	phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, CCK, RF_1TX, base );
+
+	rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][1] >> 24 ) & 0xFF; 
+	base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
+	phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, OFDM, RF_1TX, base );
+
+	rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][3] >> 24 ) & 0xFF; 
+	base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
+	phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, HT_MCS0_MCS7, RF_1TX, base );
+
+	rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][5] >> 24 ) & 0xFF; 
+	base = ( rawValue >> 4) * 10 + ( rawValue & 0xF );
+	phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, HT_MCS8_MCS15, RF_2TX, base );
+
+	rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][7] & 0xFF ); 
+	base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
+	phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, CCK, RF_1TX, base );
+
+	rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][9] >> 24 ) & 0xFF; 
+	base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
+	phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, OFDM, RF_1TX, base );
+
+	rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][11] >> 24 ) & 0xFF; 
+	base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
+	phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, HT_MCS0_MCS7, RF_1TX, base );
+
+	rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][13] >> 24 ) & 0xFF; 
+	base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF );
+	phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, HT_MCS8_MCS15, RF_2TX, base );
+}
+#endif /* TX_POWER_BY_RATE_OLD */
+
+VOID
+phy_StoreTxPowerByRateBase(	
+	IN	PADAPTER	pAdapter
+	)
+{
+	struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter);
+
+	u8 rate_sec_base[RATE_SECTION_NUM] = {
+		MGN_11M,
+		MGN_54M,
+		MGN_MCS7,
+		MGN_MCS15,
+		MGN_MCS23,
+		MGN_MCS31,
+		MGN_VHT1SS_MCS7,
+		MGN_VHT2SS_MCS7,
+		MGN_VHT3SS_MCS7,
+		MGN_VHT4SS_MCS7,
+	};
+
+	u8 band, path, rs, tx_num, base, index;
+
+	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+
+		for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
+			/* TODO: 8814A's NumTotalRFPath differs at probe(3) and up(4), need fixed
+			if (path >= hal_data->NumTotalRFPath)
+				break;
+			*/
+
+			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+				tx_num = rate_section_to_tx_num(rs);
+				if (tx_num >= hal_spec->nss_num)
+					continue;
+
+				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+					continue;
+
+				base = _PHY_GetTxPowerByRate(pAdapter, band, path, tx_num, rate_sec_base[rs]);
+				phy_SetTxPowerByRateBase(pAdapter, band, path, rs, tx_num, base);
+			}
+		}
+	}
+}
+
+#ifdef TX_POWER_BY_RATE_OLD
+u8
+PHY_GetRateSectionIndexOfTxPowerByRate(
+	IN	PADAPTER	pAdapter,
+	IN	u32			RegAddr,
+	IN	u32			BitMask
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA( pAdapter );
+	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
+	u8 			index = 0;
+	
+	if ( pDM_Odm->PhyRegPgVersion == 0 )
+	{
+		switch ( RegAddr )
+		{
+			case rTxAGC_A_Rate18_06:	 index = 0;		break;
+			case rTxAGC_A_Rate54_24:	 index = 1;		break;
+			case rTxAGC_A_CCK1_Mcs32:	 index = 6;		break;
+			case rTxAGC_B_CCK11_A_CCK2_11:
+				if ( BitMask == bMaskH3Bytes )
+					index = 7;
+				else if ( BitMask == 0x000000ff )
+					index = 15;
+				break;
+				
+			case rTxAGC_A_Mcs03_Mcs00:	 index = 2;		break;
+			case rTxAGC_A_Mcs07_Mcs04:	 index = 3;		break;
+			case rTxAGC_A_Mcs11_Mcs08:	 index = 4;		break;
+			case rTxAGC_A_Mcs15_Mcs12:	 index = 5;		break;
+			case rTxAGC_B_Rate18_06:	 index = 8;		break;
+			case rTxAGC_B_Rate54_24:	 index = 9;		break;
+			case rTxAGC_B_CCK1_55_Mcs32: index = 14;	break;
+			case rTxAGC_B_Mcs03_Mcs00:	 index = 10;	break;
+			case rTxAGC_B_Mcs07_Mcs04:	 index = 11;	break;
+			case rTxAGC_B_Mcs11_Mcs08:	 index = 12;	break;
+			case rTxAGC_B_Mcs15_Mcs12:	 index = 13;	break;
+			default:
+				DBG_871X("Invalid RegAddr 0x3%x in PHY_GetRateSectionIndexOfTxPowerByRate()", RegAddr );
+				break;
+		};
+	}
+	
+	return index;
+}
+#endif /* TX_POWER_BY_RATE_OLD */
+
+VOID
+PHY_GetRateValuesOfTxPowerByRate(
+	IN	PADAPTER pAdapter,
+	IN	u32 RegAddr,
+	IN	u32 BitMask,
+	IN	u32 Value,
+	OUT	u8 *Rate,
+	OUT	s8 *PwrByRateVal,
+	OUT	u8 *RateNum
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA( pAdapter );
+	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
+	u8	 			index = 0, i = 0;
+	
+	switch ( RegAddr )
+	{
+		case rTxAGC_A_Rate18_06:
+		case rTxAGC_B_Rate18_06:
+			Rate[0] = MGN_6M;
+			Rate[1] = MGN_9M;
+			Rate[2] = MGN_12M;
+			Rate[3] = MGN_18M;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+			
+		case rTxAGC_A_Rate54_24:
+		case rTxAGC_B_Rate54_24:
+			Rate[0] = MGN_24M;
+			Rate[1] = MGN_36M;
+			Rate[2] = MGN_48M;
+			Rate[3] = MGN_54M;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+			
+		case rTxAGC_A_CCK1_Mcs32:
+			Rate[0] = MGN_1M;
+			PwrByRateVal[0] = ( s8 ) ( ( ( ( Value >> (8 + 4) ) & 0xF ) ) * 10 + 
+											( ( Value >> 8 ) & 0xF ) );
+			*RateNum = 1;
+			break;
+			
+		case rTxAGC_B_CCK11_A_CCK2_11:
+			if ( BitMask == 0xffffff00 )
+			{
+				Rate[0] = MGN_2M;
+				Rate[1] = MGN_5_5M;
+				Rate[2] = MGN_11M;
+				for ( i = 1; i < 4; ++ i )
+				{
+					PwrByRateVal[i - 1] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+													( ( Value >> (i * 8) ) & 0xF ) );
+				}
+				*RateNum = 3;
+			}
+			else if ( BitMask == 0x000000ff )
+			{
+				Rate[0] = MGN_11M;
+				PwrByRateVal[0] = ( s8 ) ( ( ( ( Value >> 4 ) & 0xF ) ) * 10 + 
+											        ( Value & 0xF ) );
+				*RateNum = 1;
+			}
+			break;
+			
+		case rTxAGC_A_Mcs03_Mcs00:
+		case rTxAGC_B_Mcs03_Mcs00:
+			Rate[0] = MGN_MCS0;
+			Rate[1] = MGN_MCS1;
+			Rate[2] = MGN_MCS2;
+			Rate[3] = MGN_MCS3;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+			
+		case rTxAGC_A_Mcs07_Mcs04:
+		case rTxAGC_B_Mcs07_Mcs04:
+			Rate[0] = MGN_MCS4;
+			Rate[1] = MGN_MCS5;
+			Rate[2] = MGN_MCS6;
+			Rate[3] = MGN_MCS7;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+			
+		case rTxAGC_A_Mcs11_Mcs08:
+		case rTxAGC_B_Mcs11_Mcs08:
+			Rate[0] = MGN_MCS8;
+			Rate[1] = MGN_MCS9;
+			Rate[2] = MGN_MCS10;
+			Rate[3] = MGN_MCS11;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+			
+		case rTxAGC_A_Mcs15_Mcs12:
+		case rTxAGC_B_Mcs15_Mcs12:
+			Rate[0] = MGN_MCS12;
+			Rate[1] = MGN_MCS13;
+			Rate[2] = MGN_MCS14;
+			Rate[3] = MGN_MCS15;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			
+			break;
+			
+		case rTxAGC_B_CCK1_55_Mcs32:
+			Rate[0] = MGN_1M;
+			Rate[1] = MGN_2M;
+			Rate[2] = MGN_5_5M;
+			for ( i = 1; i < 4; ++ i )
+			{
+				PwrByRateVal[i - 1] = ( s8 ) ( ( ( ( Value >> ( i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> ( i * 8) ) & 0xF ) );
+			}
+			*RateNum = 3;
+			break;
+			
+		case 0xC20:
+		case 0xE20:
+		case 0x1820:
+		case 0x1a20:
+			Rate[0] = MGN_1M;
+			Rate[1] = MGN_2M;
+			Rate[2] = MGN_5_5M;
+			Rate[3] = MGN_11M;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+			
+		case 0xC24:
+		case 0xE24:
+		case 0x1824:
+		case 0x1a24:
+			Rate[0] = MGN_6M;
+			Rate[1] = MGN_9M;
+			Rate[2] = MGN_12M;
+			Rate[3] = MGN_18M;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC28:
+		case 0xE28:
+		case 0x1828:
+		case 0x1a28:
+			Rate[0] = MGN_24M;
+			Rate[1] = MGN_36M;
+			Rate[2] = MGN_48M;
+			Rate[3] = MGN_54M;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC2C:
+		case 0xE2C:
+		case 0x182C:
+		case 0x1a2C:
+			Rate[0] = MGN_MCS0;
+			Rate[1] = MGN_MCS1;
+			Rate[2] = MGN_MCS2;
+			Rate[3] = MGN_MCS3;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC30:
+		case 0xE30:
+		case 0x1830:
+		case 0x1a30:
+			Rate[0] = MGN_MCS4;
+			Rate[1] = MGN_MCS5;
+			Rate[2] = MGN_MCS6;
+			Rate[3] = MGN_MCS7;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC34:
+		case 0xE34:
+		case 0x1834:
+		case 0x1a34:
+			Rate[0] = MGN_MCS8;
+			Rate[1] = MGN_MCS9;
+			Rate[2] = MGN_MCS10;
+			Rate[3] = MGN_MCS11;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC38:
+		case 0xE38:
+		case 0x1838:
+		case 0x1a38:
+			Rate[0] = MGN_MCS12;
+			Rate[1] = MGN_MCS13;
+			Rate[2] = MGN_MCS14;
+			Rate[3] = MGN_MCS15;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC3C:
+		case 0xE3C:
+		case 0x183C:
+		case 0x1a3C:
+			Rate[0] = MGN_VHT1SS_MCS0;
+			Rate[1] = MGN_VHT1SS_MCS1;
+			Rate[2] = MGN_VHT1SS_MCS2;
+			Rate[3] = MGN_VHT1SS_MCS3;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC40:
+		case 0xE40:
+		case 0x1840:
+		case 0x1a40:
+			Rate[0] = MGN_VHT1SS_MCS4;
+			Rate[1] = MGN_VHT1SS_MCS5;
+			Rate[2] = MGN_VHT1SS_MCS6;
+			Rate[3] = MGN_VHT1SS_MCS7;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC44:
+		case 0xE44:
+		case 0x1844:
+		case 0x1a44:
+			Rate[0] = MGN_VHT1SS_MCS8;
+			Rate[1] = MGN_VHT1SS_MCS9;
+			Rate[2] = MGN_VHT2SS_MCS0;
+			Rate[3] = MGN_VHT2SS_MCS1;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC48:
+		case 0xE48:
+		case 0x1848:
+		case 0x1a48:
+			Rate[0] = MGN_VHT2SS_MCS2;
+			Rate[1] = MGN_VHT2SS_MCS3;
+			Rate[2] = MGN_VHT2SS_MCS4;
+			Rate[3] = MGN_VHT2SS_MCS5;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xC4C:
+		case 0xE4C:
+		case 0x184C:
+		case 0x1a4C:
+			Rate[0] = MGN_VHT2SS_MCS6;
+			Rate[1] = MGN_VHT2SS_MCS7;
+			Rate[2] = MGN_VHT2SS_MCS8;
+			Rate[3] = MGN_VHT2SS_MCS9;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xCD8:
+		case 0xED8:
+		case 0x18D8:
+		case 0x1aD8:
+			Rate[0] = MGN_MCS16;
+			Rate[1] = MGN_MCS17;
+			Rate[2] = MGN_MCS18;
+			Rate[3] = MGN_MCS19;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xCDC:
+		case 0xEDC:
+		case 0x18DC:
+		case 0x1aDC:
+			Rate[0] = MGN_MCS20;
+			Rate[1] = MGN_MCS21;
+			Rate[2] = MGN_MCS22;
+			Rate[3] = MGN_MCS23;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xCE0:
+		case 0xEE0:
+		case 0x18E0:
+		case 0x1aE0:
+			Rate[0] = MGN_VHT3SS_MCS0;
+			Rate[1] = MGN_VHT3SS_MCS1;
+			Rate[2] = MGN_VHT3SS_MCS2;
+			Rate[3] = MGN_VHT3SS_MCS3;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xCE4:
+		case 0xEE4:
+		case 0x18E4:
+		case 0x1aE4:
+			Rate[0] = MGN_VHT3SS_MCS4;
+			Rate[1] = MGN_VHT3SS_MCS5;
+			Rate[2] = MGN_VHT3SS_MCS6;
+			Rate[3] = MGN_VHT3SS_MCS7;
+			for ( i = 0; i < 4; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 4;
+			break;
+
+		case 0xCE8:
+		case 0xEE8:
+		case 0x18E8:
+		case 0x1aE8:
+			Rate[0] = MGN_VHT3SS_MCS8;
+			Rate[1] = MGN_VHT3SS_MCS9;
+			for ( i = 0; i < 2; ++ i )
+			{
+				PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + 
+												( ( Value >> (i * 8) ) & 0xF ) );
+			}
+			*RateNum = 2;
+			break;
+			
+		default:
+			DBG_871X_LEVEL(_drv_always_, "Invalid RegAddr 0x%x in %s()\n", RegAddr, __func__);
+			break;
+	};
+}
+
+void
+PHY_StoreTxPowerByRateNew(
+	IN	PADAPTER	pAdapter,
+	IN	u32			Band,
+	IN	u32			RfPath,
+	IN	u32			TxNum,
+	IN	u32			RegAddr,
+	IN	u32			BitMask,
+	IN	u32			Data
+	)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+	u8	i = 0, rates[4] = {0}, rateNum = 0;
+	s8	PwrByRateVal[4] = {0};
+
+	PHY_GetRateValuesOfTxPowerByRate(pAdapter, RegAddr, BitMask, Data, rates, PwrByRateVal, &rateNum);
+
+	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+		DBG_871X_LEVEL(_drv_always_, "Invalid Band %d\n", Band);
+		return;
+	}
+
+	if (RfPath > ODM_RF_PATH_D) {
+		DBG_871X_LEVEL(_drv_always_, "Invalid RfPath %d\n", RfPath);
+		return;
+	}
+
+	if (TxNum > ODM_RF_PATH_D) {
+		DBG_871X_LEVEL(_drv_always_, "Invalid TxNum %d\n", TxNum);
+		return;
+	}
+
+	for (i = 0; i < rateNum; ++i) {
+		u8 rate_idx = PHY_GetRateIndexOfTxPowerByRate(rates[i]);
+
+		if (IS_1T_RATE(rates[i]))
+			pHalData->TxPwrByRateOffset[Band][RfPath][RF_1TX][rate_idx] = PwrByRateVal[i];
+		else if (IS_2T_RATE(rates[i]))
+			pHalData->TxPwrByRateOffset[Band][RfPath][RF_2TX][rate_idx] = PwrByRateVal[i];
+		else if (IS_3T_RATE(rates[i]))
+			pHalData->TxPwrByRateOffset[Band][RfPath][RF_3TX][rate_idx] = PwrByRateVal[i];
+		else if (IS_4T_RATE(rates[i]))
+			pHalData->TxPwrByRateOffset[Band][RfPath][RF_4TX][rate_idx] = PwrByRateVal[i];
+		else
+			rtw_warn_on(1);
+	}
+}
+
+#ifdef TX_POWER_BY_RATE_OLD
+void 
+PHY_StoreTxPowerByRateOld(
+	IN	PADAPTER		pAdapter,
+	IN	u32				RegAddr,
+	IN	u32				BitMask,
+	IN	u32				Data
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	u8			index = PHY_GetRateSectionIndexOfTxPowerByRate( pAdapter, RegAddr, BitMask );
+
+	pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][index] = Data;
+	//DBG_871X("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", pHalData->pwrGroupCnt,
+	//	pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0]);
+}
+#endif /* TX_POWER_BY_RATE_OLD */
+
+VOID
+PHY_InitTxPowerByRate(
+	IN	PADAPTER	pAdapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	u8	band = 0, rfPath = 0, TxNum = 0, rate = 0, i = 0, j = 0;
+
+	if ( IS_HARDWARE_TYPE_8188E( pAdapter ) )
+	{
+		for ( i = 0; i < MAX_PG_GROUP; ++i )
+			for ( j = 0; j < 16; ++j )
+				pHalData->MCSTxPowerLevelOriginalOffset[i][j] = 0;
+	}
+	else
+	{
+		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 = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate )
+							pHalData->TxPwrByRateOffset[band][rfPath][TxNum][rate] = 0;
+	}
+}
+
+VOID
+PHY_StoreTxPowerByRate(
+	IN	PADAPTER	pAdapter,
+	IN	u32			Band,
+	IN	u32			RfPath,
+	IN	u32			TxNum,
+	IN	u32			RegAddr,
+	IN	u32			BitMask,
+	IN	u32			Data
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	PDM_ODM_T  		pDM_Odm = &pHalData->odmpriv;
+	
+	if ( pDM_Odm->PhyRegPgVersion > 0 )
+	{
+		PHY_StoreTxPowerByRateNew( pAdapter, Band, RfPath, TxNum, RegAddr, BitMask, Data );
+	}
+#ifdef TX_POWER_BY_RATE_OLD
+	else if ( pDM_Odm->PhyRegPgVersion == 0 )
+	{
+		PHY_StoreTxPowerByRateOld( pAdapter, RegAddr, BitMask, Data );
+	
+		if ( RegAddr == rTxAGC_A_Mcs15_Mcs12 && pHalData->rf_type == RF_1T1R )
+			pHalData->pwrGroupCnt++;
+		else if ( RegAddr == rTxAGC_B_Mcs15_Mcs12 && pHalData->rf_type != RF_1T1R )
+			pHalData->pwrGroupCnt++;
+	}
+#endif
+	else
+		DBG_871X("Invalid PHY_REG_PG.txt version %d\n",  pDM_Odm->PhyRegPgVersion );
+	
+}
+
+#ifdef TX_POWER_BY_RATE_OLD
+VOID 
+phy_ConvertTxPowerByRateByBase(
+	IN	u32*		pData,
+	IN	u8			Start,
+	IN	u8			End,
+	IN	u8			BaseValue
+	)
+{
+	s8	i = 0;
+	u8	TempValue = 0;
+	u32	TempData = 0;
+	
+	for ( i = 3; i >= 0; --i )
+	{
+		if ( i >= Start && i <= End )
+		{
+			// Get the exact value
+			TempValue = ( u8 ) ( *pData >> ( i * 8 ) ) & 0xF; 
+			TempValue += ( ( u8 ) ( ( *pData >> ( i * 8 + 4 ) ) & 0xF ) ) * 10; 
+			
+			// Change the value to a relative value
+			TempValue = ( TempValue > BaseValue ) ? TempValue - BaseValue : BaseValue - TempValue;
+		}
+		else
+		{
+			TempValue = ( u8 ) ( *pData >> ( i * 8 ) ) & 0xFF;
+		}
+		
+		TempData <<= 8;
+		TempData |= TempValue;
+	}
+
+	*pData = TempData;
+}
+
+
+VOID
+PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld(
+	IN	PADAPTER	pAdapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA( pAdapter );
+	u8			base = 0;
+	
+	//DBG_871X("===>PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld()\n" );
+	
+	// CCK
+	base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, CCK );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][6] ), 1, 1, base );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][7] ), 1, 3, base );
+
+	// OFDM
+	base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, OFDM );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][0] ), 0, 3, base );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][1] ),	0, 3, base );
+
+	// HT MCS0~7
+	base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, HT_MCS0_MCS7 );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][2] ),	0, 3, base );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][3] ),	0, 3, base );
+
+	// HT MCS8~15
+	base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_2TX, HT_MCS8_MCS15 );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][4] ), 0, 3, base );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][5] ), 0, 3, base );
+
+	// CCK
+	base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, CCK );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][14] ), 1, 3, base );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][15] ), 0, 0, base );
+
+	// OFDM
+	base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, OFDM );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][8] ), 0, 3, base );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][9] ),	0, 3, base );
+
+	// HT MCS0~7
+	base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, HT_MCS0_MCS7 );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][10] ), 0, 3, base );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][11] ), 0, 3, base );
+
+	// HT MCS8~15
+	base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_2TX, HT_MCS8_MCS15 );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][12] ), 0, 3, base );
+	phy_ConvertTxPowerByRateByBase( 
+			&( pHalData->MCSTxPowerLevelOriginalOffset[0][13] ), 0, 3, base );
+
+	//DBG_871X("<===PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld()\n" );
+}
+#endif /* TX_POWER_BY_RATE_OLD */
+
+VOID
+phy_ConvertTxPowerByRateInDbmToRelativeValues(
+	IN	PADAPTER	pAdapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA( pAdapter );
+	u8 			base = 0, i = 0, value = 0,
+				band = 0, path = 0, txNum = 0, index = 0, 
+				startIndex = 0, endIndex = 0;
+	u8			cckRates[4] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M},
+				ofdmRates[8] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M},
+				mcs0_7Rates[8] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7},
+				mcs8_15Rates[8] = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15},
+				mcs16_23Rates[8] = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23},
+				vht1ssRates[10] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4, 
+							   MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9},
+				vht2ssRates[10] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4, 
+							   MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9},
+				vht3ssRates[10] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4, 
+								   MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9};
+
+	//DBG_871X("===>PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" );
+
+	for ( band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band )
+	{
+		for ( path = ODM_RF_PATH_A; path <= ODM_RF_PATH_D; ++path )
+		{
+			for ( txNum = RF_1TX; txNum < RF_MAX_TX_NUM; ++txNum )
+			{
+				// CCK
+				base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_11M );
+				for ( i = 0; i < sizeof( cckRates ); ++i )
+				{
+					value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, cckRates[i] );
+					PHY_SetTxPowerByRate( pAdapter, band, path, txNum, cckRates[i], value - base );
+				}
+
+				// OFDM
+				base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_54M );
+				for ( i = 0; i < sizeof( ofdmRates ); ++i )
+				{
+					value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, ofdmRates[i] );
+					PHY_SetTxPowerByRate( pAdapter, band, path, txNum, ofdmRates[i], value - base );
+				}
+				
+				// HT MCS0~7
+				base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS7 );
+				for ( i = 0; i < sizeof( mcs0_7Rates ); ++i )
+				{
+					value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs0_7Rates[i] );
+					PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs0_7Rates[i], value - base );
+				}
+
+				// HT MCS8~15
+				base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS15 );
+				for ( i = 0; i < sizeof( mcs8_15Rates ); ++i )
+				{
+					value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs8_15Rates[i] );
+					PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs8_15Rates[i], value - base );
+				}
+
+				// HT MCS16~23
+				base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS23 );
+				for ( i = 0; i < sizeof( mcs16_23Rates ); ++i )
+				{
+					value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs16_23Rates[i] );
+					PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs16_23Rates[i], value - base );
+				}
+
+				// VHT 1SS
+				base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT1SS_MCS7 );
+				for ( i = 0; i < sizeof( vht1ssRates ); ++i )
+				{
+					value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht1ssRates[i] );
+					PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht1ssRates[i], value - base );
+				}
+
+				// VHT 2SS
+				base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT2SS_MCS7 );
+				for ( i = 0; i < sizeof( vht2ssRates ); ++i )
+				{
+					value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht2ssRates[i] );
+					PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht2ssRates[i], value - base );
+				}
+
+				// VHT 3SS
+				base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT3SS_MCS7 );
+				for ( i = 0; i < sizeof( vht3ssRates ); ++i )
+				{
+					value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht3ssRates[i] );
+					PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht3ssRates[i], value - base );
+				}
+			}
+		}
+	}
+
+	//DBG_871X("<===PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" );
+}
+
+/*
+  * This function must be called if the value in the PHY_REG_PG.txt(or header)
+  * is exact dBm values
+  */
+VOID
+PHY_TxPowerByRateConfiguration(
+	IN  PADAPTER			pAdapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA( pAdapter);
+
+	phy_StoreTxPowerByRateBase( pAdapter );
+	phy_ConvertTxPowerByRateInDbmToRelativeValues( pAdapter );
+}
+
+VOID 
+PHY_SetTxPowerIndexByRateSection(
+	IN	PADAPTER		pAdapter,
+	IN	u8				RFPath,	
+	IN	u8				Channel,
+	IN	u8				RateSection
+	)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(pAdapter);
+
+	if ( RateSection == CCK )
+	{
+		u8	cckRates[]   = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M};
+		if ( pHalData->CurrentBandType == BAND_ON_2_4G )
+			PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+									  cckRates, sizeof(cckRates)/sizeof(u8) );
+			
+	}
+	else if ( RateSection == OFDM )
+	{
+		u8	ofdmRates[]  = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M};
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+									 ofdmRates, sizeof(ofdmRates)/sizeof(u8));
+		
+	}
+	else if ( RateSection == HT_MCS0_MCS7 )
+	{
+		u8	htRates1T[]  = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7};
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+									 htRates1T, sizeof(htRates1T)/sizeof(u8));
+
+	}
+	else if ( RateSection == HT_MCS8_MCS15 )
+	{
+		u8	htRates2T[]  = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15};
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+								  	 htRates2T, sizeof(htRates2T)/sizeof(u8));
+		
+	}
+	else if ( RateSection == HT_MCS16_MCS23 )
+	{
+		u1Byte	htRates3T[]  = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23};
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+								  	 htRates3T, sizeof(htRates3T)/sizeof(u1Byte));
+		
+	}
+	else if ( RateSection == HT_MCS24_MCS31 )
+	{
+		u1Byte	htRates4T[]  = {MGN_MCS24, MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29, MGN_MCS30, MGN_MCS31};
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+								  	 htRates4T, sizeof(htRates4T)/sizeof(u1Byte));
+		
+	}
+	else if ( RateSection == VHT_1SSMCS0_1SSMCS9 )
+	{	
+		u8	vhtRates1T[] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4, 
+                            	MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9};
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+									vhtRates1T, sizeof(vhtRates1T)/sizeof(u8));
+
+	}
+	else if ( RateSection == VHT_2SSMCS0_2SSMCS9 )
+	{
+		u8	vhtRates2T[] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4, 
+                            	MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9};
+
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+								  vhtRates2T, sizeof(vhtRates2T)/sizeof(u8));
+	}
+	else if ( RateSection == VHT_3SSMCS0_3SSMCS9 )
+	{
+		u1Byte	vhtRates3T[] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4, 
+                            	MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9};
+
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+								  vhtRates3T, sizeof(vhtRates3T)/sizeof(u1Byte));
+	}
+	else if ( RateSection == VHT_4SSMCS0_4SSMCS9 )
+	{
+		u1Byte	vhtRates4T[] = {MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4, 
+                            	MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9};
+
+		PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel,
+								  vhtRates4T, sizeof(vhtRates4T)/sizeof(u1Byte));
+	}
+	else
+	{
+		DBG_871X("Invalid RateSection %d in %s", RateSection, __FUNCTION__ );
+	}
+}
+
+BOOLEAN 
+phy_GetChnlIndex(
+	IN	u8 	Channel,
+	OUT u8*	ChannelIdx
+	)
+{
+	u8  i = 0;
+	BOOLEAN bIn24G=_TRUE;
+
+	if (Channel <= 14) {
+		bIn24G = _TRUE;
+		*ChannelIdx = Channel - 1;
+	} else {
+		bIn24G = _FALSE;	
+
+		for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
+			if (center_ch_5g_all[i] == Channel) {
+				*ChannelIdx = i;
+				return bIn24G;
+			}
+		}
+	}
+
+	return bIn24G;
+}
+
+u8
+PHY_GetTxPowerIndexBase(
+	IN	PADAPTER		pAdapter,
+	IN	u8				RFPath,
+	IN	u8				Rate,	
+	IN	CHANNEL_WIDTH	BandWidth,	
+	IN	u8				Channel,
+	OUT PBOOLEAN		bIn24G
+	)
+{
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(pAdapter);
+	PDM_ODM_T			pDM_Odm = &pHalData->odmpriv;
+	u8					i = 0;	//default set to 1S
+	u8					txPower = 0;
+	u8					chnlIdx = (Channel-1);
+	
+	if (HAL_IsLegalChannel(pAdapter, Channel) == _FALSE)
+	{
+		chnlIdx = 0;
+		DBG_871X("Illegal channel!!\n");
+	}
+
+	*bIn24G = phy_GetChnlIndex(Channel, &chnlIdx);
+
+	//DBG_871X("[%s] Channel Index: %d\n", (*bIn24G?"2.4G":"5G"), chnlIdx);
+
+	if (*bIn24G) //3 ============================== 2.4 G ==============================
+	{
+		if ( IS_CCK_RATE(Rate) )
+		{
+			txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx];	
+		}
+		else if ( MGN_6M <= Rate )
+		{				
+			txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx];
+		}
+		else
+		{
+			DBG_871X("PHY_GetTxPowerIndexBase: INVALID Rate.\n");
+		}
+
+		//DBG_871X("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", 
+		//		((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower);
+		
+		// OFDM-1T
+		if ( (MGN_6M <= Rate && Rate <= MGN_54M) && ! IS_CCK_RATE(Rate) )
+		{
+			txPower += pHalData->OFDM_24G_Diff[RFPath][TX_1S];
+			//DBG_871X("+PowerDiff 2.4G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_24G_Diff[RFPath][TX_1S]);
+		}
+		// BW20-1S, BW20-2S
+		if (BandWidth == CHANNEL_WIDTH_20)
+		{
+			if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW20_24G_Diff[RFPath][TX_1S];
+			if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW20_24G_Diff[RFPath][TX_2S];
+			if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW20_24G_Diff[RFPath][TX_3S];
+			if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW20_24G_Diff[RFPath][TX_4S];
+
+			//DBG_871X("+PowerDiff 2.4G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), 
+			//	pHalData->BW20_24G_Diff[RFPath][TX_1S], pHalData->BW20_24G_Diff[RFPath][TX_2S], 
+			//	pHalData->BW20_24G_Diff[RFPath][TX_3S], pHalData->BW20_24G_Diff[RFPath][TX_4S]);
+		}
+		// BW40-1S, BW40-2S
+		else if (BandWidth == CHANNEL_WIDTH_40)
+		{
+			if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
+			if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
+			if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
+			if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];			 
+
+			//DBG_871X("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), 
+			//	pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S],
+			//	pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]);
+		}
+		// Willis suggest adopt BW 40M power index while in BW 80 mode
+		else if ( BandWidth == CHANNEL_WIDTH_80 )
+		{
+			if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
+			if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
+			if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
+			if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];
+
+			//DBG_871X("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4T) = (%d, %d, %d, %d) P.S. Current is in BW 80MHz\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), 
+			//	pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S],
+			//	pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]);
+		}
+	}
+	else //3 ============================== 5 G ==============================
+	{
+		if ( MGN_6M <= Rate )
+		{				
+			txPower = pHalData->Index5G_BW40_Base[RFPath][chnlIdx];
+		}
+		else
+		{
+			DBG_871X("===> mpt_ProQueryCalTxPower_Jaguar: INVALID Rate.\n");
+		}
+
+		//DBG_871X("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", 
+		//	((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower);
+
+		// OFDM-1T
+		if ( (MGN_6M <= Rate && Rate <= MGN_54M) && ! IS_CCK_RATE(Rate))
+		{
+			txPower += pHalData->OFDM_5G_Diff[RFPath][TX_1S];
+			//DBG_871X("+PowerDiff 5G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_5G_Diff[RFPath][TX_1S]);
+		}
+		
+		// BW20-1S, BW20-2S
+		if (BandWidth == CHANNEL_WIDTH_20)
+		{
+			if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW20_5G_Diff[RFPath][TX_1S];
+			if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW20_5G_Diff[RFPath][TX_2S];
+			if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW20_5G_Diff[RFPath][TX_3S];
+			if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW20_5G_Diff[RFPath][TX_4S];
+
+			//DBG_871X("+PowerDiff 5G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), 
+			//	pHalData->BW20_5G_Diff[RFPath][TX_1S], pHalData->BW20_5G_Diff[RFPath][TX_2S],
+			//	pHalData->BW20_5G_Diff[RFPath][TX_3S], pHalData->BW20_5G_Diff[RFPath][TX_4S]);
+		}
+		// BW40-1S, BW40-2S
+		else if (BandWidth == CHANNEL_WIDTH_40)
+		{
+			if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_5G_Diff[RFPath][TX_1S];
+			if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_5G_Diff[RFPath][TX_2S];
+			if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_5G_Diff[RFPath][TX_3S];
+			if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW40_5G_Diff[RFPath][TX_4S];
+
+			//DBG_871X("+PowerDiff 5G(RF-%c): (BW40-1S, BW40-2S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), 
+			//	pHalData->BW40_5G_Diff[RFPath][TX_1S], pHalData->BW40_5G_Diff[RFPath][TX_2S],
+			//	pHalData->BW40_5G_Diff[RFPath][TX_3S], pHalData->BW40_5G_Diff[RFPath][TX_4S]);
+		}
+		// BW80-1S, BW80-2S
+		else if (BandWidth== CHANNEL_WIDTH_80)
+		{
+			// <20121220, Kordan> Get the index of array "Index5G_BW80_Base".
+			for (i = 0; i < CENTER_CH_5G_80M_NUM; ++i)
+				if (center_ch_5g_80m[i] == Channel)
+					chnlIdx = i;
+
+			txPower = pHalData->Index5G_BW80_Base[RFPath][chnlIdx];
+
+			if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31)  || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += + pHalData->BW80_5G_Diff[RFPath][TX_1S];
+			if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW80_5G_Diff[RFPath][TX_2S];
+			if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW80_5G_Diff[RFPath][TX_3S];
+			if ( (MGN_MCS23 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+				txPower += pHalData->BW80_5G_Diff[RFPath][TX_4S];
+
+			//DBG_871X("+PowerDiff 5G(RF-%c): (BW80-1S, BW80-2S, BW80-3S, BW80-4S) = (%d, %d, %d, %d)\n",((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), 
+			//	pHalData->BW80_5G_Diff[RFPath][TX_1S], pHalData->BW80_5G_Diff[RFPath][TX_2S],
+			//	pHalData->BW80_5G_Diff[RFPath][TX_3S], pHalData->BW80_5G_Diff[RFPath][TX_4S]);
+		}
+	}
+
+	return txPower;	
+}
+
+s8
+PHY_GetTxPowerTrackingOffset( 
+	PADAPTER	pAdapter,
+	u8			RFPath,
+	u8			Rate
+	)
+{
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(pAdapter);
+	PDM_ODM_T			pDM_Odm = &pHalData->odmpriv;	
+	s8	offset = 0;
+	
+	if( pDM_Odm->RFCalibrateInfo.TxPowerTrackControl  == _FALSE)
+		return offset;
+	
+	if ((Rate == MGN_1M) ||(Rate == MGN_2M)||(Rate == MGN_5_5M)||(Rate == MGN_11M))
+	{ 
+		offset = pDM_Odm->RFCalibrateInfo.Remnant_CCKSwingIdx;
+		/*DBG_871X("+Remnant_CCKSwingIdx = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_CCKSwingIdx);*/
+	}
+	else
+	{
+		offset = pDM_Odm->RFCalibrateInfo.Remnant_OFDMSwingIdx[RFPath]; 
+		/*DBG_871X("+Remanant_OFDMSwingIdx[RFPath %u][Rate 0x%x] = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath]);	*/	
+		
+	}
+
+	return offset;
+}
+
+u8
+PHY_GetRateIndexOfTxPowerByRate(
+	IN	u8		Rate
+	)
+{
+	u8	index = 0;
+	switch ( Rate )
+	{
+		case MGN_1M: index = 0; break;
+		case MGN_2M: index = 1; break;
+		case MGN_5_5M: index = 2; break;
+		case MGN_11M: index = 3; break;
+		case MGN_6M: index = 4; break;
+		case MGN_9M: index = 5; break;
+		case MGN_12M: index = 6; break;
+		case MGN_18M: index = 7; break;
+		case MGN_24M: index = 8; break;
+		case MGN_36M: index = 9; break;
+		case MGN_48M: index = 10; break;
+		case MGN_54M: index = 11; break;
+		case MGN_MCS0: index = 12; break;
+		case MGN_MCS1: index = 13; break;
+		case MGN_MCS2: index = 14; break;
+		case MGN_MCS3: index = 15; break;
+		case MGN_MCS4: index = 16; break;
+		case MGN_MCS5: index = 17; break;
+		case MGN_MCS6: index = 18; break;
+		case MGN_MCS7: index = 19; break;
+		case MGN_MCS8: index = 20; break;
+		case MGN_MCS9: index = 21; break;
+		case MGN_MCS10: index = 22; break;
+		case MGN_MCS11: index = 23; break;
+		case MGN_MCS12: index = 24; break;
+		case MGN_MCS13: index = 25; break;
+		case MGN_MCS14: index = 26; break;
+		case MGN_MCS15: index = 27; break;
+		case MGN_MCS16: index = 28; break;
+		case MGN_MCS17: index = 29; break;
+		case MGN_MCS18: index = 30; break;
+		case MGN_MCS19: index = 31; break;
+		case MGN_MCS20: index = 32; break;
+		case MGN_MCS21: index = 33; break;
+		case MGN_MCS22: index = 34; break;
+		case MGN_MCS23: index = 35; break;
+		case MGN_MCS24: index = 36; break;
+		case MGN_MCS25: index = 37; break;
+		case MGN_MCS26: index = 38; break;
+		case MGN_MCS27: index = 39; break;
+		case MGN_MCS28: index = 40; break;
+		case MGN_MCS29: index = 41; break;
+		case MGN_MCS30: index = 42; break;
+		case MGN_MCS31: index = 43; break;
+		case MGN_VHT1SS_MCS0: index = 44; break;
+		case MGN_VHT1SS_MCS1: index = 45; break;
+		case MGN_VHT1SS_MCS2: index = 46; break;
+		case MGN_VHT1SS_MCS3: index = 47; break;
+		case MGN_VHT1SS_MCS4: index = 48; break;
+		case MGN_VHT1SS_MCS5: index = 49; break;
+		case MGN_VHT1SS_MCS6: index = 50; break;
+		case MGN_VHT1SS_MCS7: index = 51; break;
+		case MGN_VHT1SS_MCS8: index = 52; break;
+		case MGN_VHT1SS_MCS9: index = 53; break;
+		case MGN_VHT2SS_MCS0: index = 54; break;
+		case MGN_VHT2SS_MCS1: index = 55; break;
+		case MGN_VHT2SS_MCS2: index = 56; break;
+		case MGN_VHT2SS_MCS3: index = 57; break;
+		case MGN_VHT2SS_MCS4: index = 58; break;
+		case MGN_VHT2SS_MCS5: index = 59; break;
+		case MGN_VHT2SS_MCS6: index = 60; break;
+		case MGN_VHT2SS_MCS7: index = 61; break;
+		case MGN_VHT2SS_MCS8: index = 62; break;
+		case MGN_VHT2SS_MCS9: index = 63; break;
+		case MGN_VHT3SS_MCS0: index = 64; break;
+		case MGN_VHT3SS_MCS1: index = 65; break;
+		case MGN_VHT3SS_MCS2: index = 66; break;
+		case MGN_VHT3SS_MCS3: index = 67; break;
+		case MGN_VHT3SS_MCS4: index = 68; break;
+		case MGN_VHT3SS_MCS5: index = 69; break;
+		case MGN_VHT3SS_MCS6: index = 70; break;
+		case MGN_VHT3SS_MCS7: index = 71; break;
+		case MGN_VHT3SS_MCS8: index = 72; break;
+		case MGN_VHT3SS_MCS9: index = 73; break;
+		case MGN_VHT4SS_MCS0: index = 74; break;
+		case MGN_VHT4SS_MCS1: index = 75; break;
+		case MGN_VHT4SS_MCS2: index = 76; break;
+		case MGN_VHT4SS_MCS3: index = 77; break;
+		case MGN_VHT4SS_MCS4: index = 78; break;
+		case MGN_VHT4SS_MCS5: index = 79; break;
+		case MGN_VHT4SS_MCS6: index = 80; break;
+		case MGN_VHT4SS_MCS7: index = 81; break;
+		case MGN_VHT4SS_MCS8: index = 82; break;
+		case MGN_VHT4SS_MCS9: index = 83; break;
+		default:
+			DBG_871X("Invalid rate 0x%x in %s\n", Rate, __FUNCTION__ );
+			break;
+	};
+
+	return index;
+}
+
+s8
+_PHY_GetTxPowerByRate(
+	IN	PADAPTER	pAdapter, 
+	IN	u8			Band, 
+	IN	u8			RFPath, 
+	IN	u8			TxNum, 
+	IN	u8			Rate
+	)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+	s8 value = 0;
+	u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
+
+	if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+		DBG_871X("Invalid band %d in %s\n", Band, __func__);
+		goto exit;
+	}
+	if (RFPath > ODM_RF_PATH_D) {
+		DBG_871X("Invalid RfPath %d in %s\n", RFPath, __func__);
+		goto exit;
+	}
+	if (TxNum >= RF_MAX_TX_NUM) {
+		DBG_871X("Invalid TxNum %d in %s\n", TxNum, __func__);
+		goto exit;
+	}
+	if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
+		DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __func__);
+		goto exit;
+	}
+
+	value = pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex];
+
+exit:
+	return value;
+}
+
+
+s8
+PHY_GetTxPowerByRate(
+	IN	PADAPTER	pAdapter,
+	IN	u8			Band,
+	IN	u8			RFPath,
+	IN	u8			TxNum,
+	IN	u8			Rate
+	)
+{
+	if (!phy_is_tx_power_by_rate_needed(pAdapter))
+		return 0;
+
+	return _PHY_GetTxPowerByRate(pAdapter, Band, RFPath, TxNum, Rate);
+}
+
+VOID
+PHY_SetTxPowerByRate( 
+	IN	PADAPTER	pAdapter, 
+	IN	u8			Band, 
+	IN	u8			RFPath, 
+	IN	u8			TxNum, 
+	IN	u8			Rate,
+	IN	s8			Value
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA( pAdapter );
+	u8	rateIndex = PHY_GetRateIndexOfTxPowerByRate( Rate );
+	
+	if ( Band != BAND_ON_2_4G && Band != BAND_ON_5G )
+	{
+		DBG_871X("Invalid band %d in %s\n", Band, __FUNCTION__ );
+		return;
+	}
+	if ( RFPath > ODM_RF_PATH_D )
+	{
+		DBG_871X("Invalid RfPath %d in %s\n", RFPath, __FUNCTION__ );
+		return;
+	}
+	if ( TxNum >= RF_MAX_TX_NUM )
+	{
+		DBG_871X( "Invalid TxNum %d in %s\n", TxNum, __FUNCTION__ );
+		return;
+	}
+	if ( rateIndex >= TX_PWR_BY_RATE_NUM_RATE )
+	{
+		DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __FUNCTION__ );
+		return;
+	}
+
+	pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex] = Value;
+}
+
+VOID
+PHY_SetTxPowerLevelByPath(
+	IN	PADAPTER	Adapter,
+	IN	u8			channel,
+	IN	u8			path
+	)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	BOOLEAN bIsIn24G = (pHalData->CurrentBandType == BAND_ON_2_4G );
+
+	//if ( pMgntInfo->RegNByteAccess == 0 )
+	{
+		if ( bIsIn24G )
+			PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, CCK );
+		
+		PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, OFDM );
+		PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS0_MCS7 );
+
+		if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter))
+			PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, VHT_1SSMCS0_1SSMCS9);
+
+		if (pHalData->NumTotalRFPath >= 2)
+		{
+			PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS8_MCS15 );
+
+			if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter))
+				PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, VHT_2SSMCS0_2SSMCS9);
+
+			if (IS_HARDWARE_TYPE_8814A(Adapter))
+			{
+				PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS16_MCS23 );
+				PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, VHT_3SSMCS0_3SSMCS9 );
+			}
+		}
+	}
+}
+
+VOID
+PHY_SetTxPowerIndexByRateArray(
+	IN	PADAPTER			pAdapter,
+	IN 	u8					RFPath,
+	IN	CHANNEL_WIDTH		BandWidth,	
+	IN	u8					Channel,
+	IN	u8*					Rates,
+	IN	u8					RateArraySize
+	)
+{
+	u32	powerIndex = 0;
+	int	i = 0;
+
+	for (i = 0; i < RateArraySize; ++i) 
+	{
+		powerIndex = PHY_GetTxPowerIndex(pAdapter, RFPath, Rates[i], BandWidth, Channel);
+		PHY_SetTxPowerIndex(pAdapter, powerIndex, RFPath, Rates[i]);
+	}
+}
+
+s8
+phy_GetWorldWideLimit(
+	s8* LimitTable
+)
+{
+	s8	min = LimitTable[0];
+	u8	i = 0;
+	
+	for (i = 0; i < MAX_REGULATION_NUM; ++i) {
+		if (LimitTable[i] < min)
+			min = LimitTable[i];
+	}
+
+	return min;
+}
+
+s8
+phy_GetChannelIndexOfTxPowerLimit(
+	IN	u8			Band,
+	IN	u8			Channel
+	)
+{
+	s8	channelIndex = -1;
+	u8	i = 0;
+
+	if (Band == BAND_ON_2_4G) {
+		channelIndex = Channel - 1;
+	} else if (Band == BAND_ON_5G) {
+		for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
+			if (center_ch_5g_all[i] == Channel)
+				channelIndex = i;
+		}
+	} else {
+		DBG_871X_LEVEL(_drv_always_, "Invalid Band %d in %s\n", Band, __func__);
+	}
+
+	if (channelIndex == -1)
+		DBG_871X_LEVEL(_drv_always_, "Invalid Channel %d of Band %d in %s\n", Channel, Band, __func__);
+
+	return channelIndex;
+}
+
+s8
+PHY_GetTxPowerLimit(
+	IN	PADAPTER			Adapter,
+	IN	u32					RegPwrTblSel,
+	IN	BAND_TYPE			Band,
+	IN	CHANNEL_WIDTH		Bandwidth,
+	IN	u8					RfPath,
+	IN	u8					DataRate,
+	IN	u8					Channel
+	)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+	s16				band = -1, regulation = -1, bandwidth = -1,
+					rateSection = -1, channel = -1;
+	s8				powerLimit = MAX_POWER_INDEX;
+
+	if ( ( Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory != 1 ) || 
+		   Adapter->registrypriv.RegEnableTxPowerLimit == 0 )
+		return MAX_POWER_INDEX;
+
+	switch (RegPwrTblSel) {
+	case 1:
+		regulation = TXPWR_LMT_ETSI;
+		break;
+	case 2:
+		regulation = TXPWR_LMT_MKK;
+		break;
+	case 3:
+		regulation = TXPWR_LMT_FCC;
+		break;
+	case 4:
+		regulation = TXPWR_LMT_WW;
+		break;
+	default:
+		regulation = (Band == BAND_ON_2_4G) ? pHalData->Regulation2_4G : pHalData->Regulation5G;
+		break;
+	}
+
+	//DBG_871X("pMgntInfo->RegPwrTblSel %d, final regulation %d\n", Adapter->registrypriv.RegPwrTblSel, regulation );
+
+	
+	if ( Band == BAND_ON_2_4G ) band = 0; 
+	else if ( Band == BAND_ON_5G ) band = 1; 
+
+	if ( Bandwidth == CHANNEL_WIDTH_20 ) bandwidth = 0;
+	else if ( Bandwidth == CHANNEL_WIDTH_40 ) bandwidth = 1;
+	else if ( Bandwidth == CHANNEL_WIDTH_80 ) bandwidth = 2;
+	else if ( Bandwidth == CHANNEL_WIDTH_160 ) bandwidth = 3;
+
+	switch ( DataRate )
+	{
+		case MGN_1M: case MGN_2M: case MGN_5_5M: case MGN_11M:
+			rateSection = 0;
+			break;
+
+		case MGN_6M: case MGN_9M: case MGN_12M: case MGN_18M:
+		case MGN_24M: case MGN_36M: case MGN_48M: case MGN_54M:
+			rateSection = 1;
+			break;
+
+		case MGN_MCS0: case MGN_MCS1: case MGN_MCS2: case MGN_MCS3: 
+		case MGN_MCS4: case MGN_MCS5: case MGN_MCS6: case MGN_MCS7:
+			rateSection = 2;
+			break;
+			
+		case MGN_MCS8: case MGN_MCS9: case MGN_MCS10: case MGN_MCS11: 
+		case MGN_MCS12: case MGN_MCS13: case MGN_MCS14: case MGN_MCS15:
+			rateSection = 3;
+			break;
+
+		case MGN_MCS16: case MGN_MCS17: case MGN_MCS18: case MGN_MCS19: 
+		case MGN_MCS20: case MGN_MCS21: case MGN_MCS22: case MGN_MCS23:
+			rateSection = 4;
+			break;
+
+		case MGN_MCS24: case MGN_MCS25: case MGN_MCS26: case MGN_MCS27: 
+		case MGN_MCS28: case MGN_MCS29: case MGN_MCS30: case MGN_MCS31:
+			rateSection = 5;
+			break;
+
+		case MGN_VHT1SS_MCS0: case MGN_VHT1SS_MCS1: case MGN_VHT1SS_MCS2:
+		case MGN_VHT1SS_MCS3: case MGN_VHT1SS_MCS4: case MGN_VHT1SS_MCS5:
+		case MGN_VHT1SS_MCS6: case MGN_VHT1SS_MCS7: case MGN_VHT1SS_MCS8:
+		case MGN_VHT1SS_MCS9:
+			rateSection = 6;
+			break;
+			
+		case MGN_VHT2SS_MCS0: case MGN_VHT2SS_MCS1: case MGN_VHT2SS_MCS2:
+		case MGN_VHT2SS_MCS3: case MGN_VHT2SS_MCS4: case MGN_VHT2SS_MCS5:
+		case MGN_VHT2SS_MCS6: case MGN_VHT2SS_MCS7: case MGN_VHT2SS_MCS8:
+		case MGN_VHT2SS_MCS9:
+			rateSection = 7;
+			break;
+
+		case MGN_VHT3SS_MCS0: case MGN_VHT3SS_MCS1: case MGN_VHT3SS_MCS2:
+		case MGN_VHT3SS_MCS3: case MGN_VHT3SS_MCS4: case MGN_VHT3SS_MCS5:
+		case MGN_VHT3SS_MCS6: case MGN_VHT3SS_MCS7: case MGN_VHT3SS_MCS8:
+		case MGN_VHT3SS_MCS9:
+			rateSection = 8;
+			break;
+
+		case MGN_VHT4SS_MCS0: case MGN_VHT4SS_MCS1: case MGN_VHT4SS_MCS2:
+		case MGN_VHT4SS_MCS3: case MGN_VHT4SS_MCS4: case MGN_VHT4SS_MCS5:
+		case MGN_VHT4SS_MCS6: case MGN_VHT4SS_MCS7: case MGN_VHT4SS_MCS8:
+		case MGN_VHT4SS_MCS9:
+			rateSection = 9;
+			break;
+
+		default:
+			DBG_871X("Wrong rate 0x%x\n", DataRate );
+			break;
+	}
+
+	if ( Band == BAND_ON_5G  && rateSection == 0 )
+			DBG_871X("Wrong rate 0x%x: No CCK in 5G Band\n", DataRate );
+
+	// workaround for wrong index combination to obtain tx power limit, 
+	// OFDM only exists in BW 20M
+	if ( rateSection == 1 )
+		bandwidth = 0;
+
+	// workaround for wrong index combination to obtain tx power limit, 
+	// CCK table will only be given in BW 20M
+	if ( rateSection == 0 )
+		bandwidth = 0;
+
+	// workaround for wrong indxe combination to obtain tx power limit, 
+	// HT on 80M will reference to HT on 40M
+	if ( ( rateSection == 2 || rateSection == 3 ) && Band == BAND_ON_5G && bandwidth == 2 ) {
+		bandwidth = 1;
+	}
+	
+	if ( Band == BAND_ON_2_4G )
+		channel = phy_GetChannelIndexOfTxPowerLimit( BAND_ON_2_4G, Channel );
+	else if ( Band == BAND_ON_5G )
+		channel = phy_GetChannelIndexOfTxPowerLimit( BAND_ON_5G, Channel );
+	else if ( Band == BAND_ON_BOTH )
+	{
+		// BAND_ON_BOTH don't care temporarily 
+	}
+	
+	if ( band == -1 || regulation == -1 || bandwidth == -1 || 
+	     rateSection == -1 || channel == -1 )
+	{
+		//DBG_871X("Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnlGroup %d]\n",
+		//	  band, regulation, bandwidth, RfPath, rateSection, channelGroup );
+
+		return MAX_POWER_INDEX;
+	}
+
+	if ( Band == BAND_ON_2_4G ) {
+		s8 limits[10] = {0}; u8 i = 0;
+		if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM)
+			bandwidth = MAX_2_4G_BANDWIDTH_NUM - 1;
+		for (i = 0; i < MAX_REGULATION_NUM; ++i)
+			limits[i] = pHalData->TxPwrLimit_2_4G[i][bandwidth][rateSection][channel][RfPath]; 
+
+		powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
+			          pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channel][RfPath];
+
+	} else if ( Band == BAND_ON_5G ) {
+		s8 limits[10] = {0}; u8 i = 0;
+		for (i = 0; i < MAX_REGULATION_NUM; ++i)
+			limits[i] = pHalData->TxPwrLimit_5G[i][bandwidth][rateSection][channel][RfPath];
+		
+		powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) : 
+					  pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channel][RfPath];
+	} else 
+		DBG_871X("No power limit table of the specified band\n" );
+
+	// combine 5G VHT & HT rate
+	// 5G 20M and 40M HT and VHT can cross reference
+	/*
+	if ( Band == BAND_ON_5G && powerLimit == MAX_POWER_INDEX ) {
+		if ( bandwidth == 0 || bandwidth == 1 ) { 
+			RT_TRACE( COMP_INIT, DBG_LOUD, ( "No power limit table of the specified band %d, bandwidth %d, ratesection %d, rf path %d\n", 
+					  band, bandwidth, rateSection, RfPath ) );
+			if ( rateSection == 2 )
+				powerLimit = pHalData->TxPwrLimit_5G[regulation]
+										[bandwidth][4][channelGroup][RfPath];
+			else if ( rateSection == 4 )
+				powerLimit = pHalData->TxPwrLimit_5G[regulation]
+										[bandwidth][2][channelGroup][RfPath];
+			else if ( rateSection == 3 )
+				powerLimit = pHalData->TxPwrLimit_5G[regulation]
+										[bandwidth][5][channelGroup][RfPath];
+			else if ( rateSection == 5 )
+				powerLimit = pHalData->TxPwrLimit_5G[regulation]
+										[bandwidth][3][channelGroup][RfPath];
+		}
+	}
+	*/
+	//DBG_871X("TxPwrLmt[Regulation %d][Band %d][BW %d][RFPath %d][Rate 0x%x][Chnl %d] = %d\n", 
+	//		regulation, pHalData->CurrentBandType, Bandwidth, RfPath, DataRate, Channel, powerLimit);
+	return powerLimit;
+}
+
+VOID
+phy_CrossReferenceHTAndVHTTxPowerLimit(
+	IN	PADAPTER			pAdapter
+	)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+	u8 regulation, bw, channel, rs, ref_rs;
+	int ht_ref_vht_5g_20_40 = 0;
+	int vht_ref_ht_5g_20_40 = 0;
+	int ht_has_ref_5g_20_40 = 0;
+	int vht_has_ref_5g_20_40 = 0;
+
+	pHalData->tx_pwr_lmt_5g_20_40_ref = 0;
+
+	for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
+
+		for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
+
+			for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
+
+				for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) {
+
+					/* 5G 20M 40M VHT and HT can cross reference */
+					if (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40) {
+						if (rs == HT_1SS)
+							ref_rs = VHT_1SS;
+						else if (rs == HT_2SS)
+							ref_rs = VHT_2SS;
+						else if (rs == HT_3SS)
+							ref_rs = VHT_3SS;
+						else if (rs == HT_4SS)
+							ref_rs = VHT_4SS;
+						else if (rs == VHT_1SS)
+							ref_rs = HT_1SS;
+						else if (rs == VHT_2SS)
+							ref_rs = HT_2SS;
+						else if (rs == VHT_3SS)
+							ref_rs = HT_3SS;
+						else if (rs == VHT_4SS)
+							ref_rs = HT_4SS;
+						else
+							continue;
+
+						if (pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A] == MAX_POWER_INDEX)
+							continue;
+
+						if (IS_HT_RATE_SECTION(rs))
+							ht_has_ref_5g_20_40++;
+						else if (IS_VHT_RATE_SECTION(rs))
+							vht_has_ref_5g_20_40++;
+						else
+							continue;
+
+						if (pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] != MAX_POWER_INDEX)
+							continue;
+
+						if (IS_HT_RATE_SECTION(rs) && IS_VHT_RATE_SECTION(ref_rs))
+							ht_ref_vht_5g_20_40++;
+						else if (IS_VHT_RATE_SECTION(rs) && IS_HT_RATE_SECTION(ref_rs))
+							vht_ref_ht_5g_20_40++;
+
+						if (0)
+							DBG_871X("reg:%u, bw:%u, ch:%u, %s ref %s\n"
+								, regulation, bw, channel
+								, rate_section_str(rs), rate_section_str(ref_rs));
+
+						pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] =
+							pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A];
+					}
+
+				}
+			}
+		}
+	}
+
+	if (0) {
+		DBG_871X("ht_ref_vht_5g_20_40:%d, ht_has_ref_5g_20_40:%d\n", ht_ref_vht_5g_20_40, ht_has_ref_5g_20_40);
+		DBG_871X("vht_ref_hht_5g_20_40:%d, vht_has_ref_5g_20_40:%d\n", vht_ref_ht_5g_20_40, vht_has_ref_5g_20_40);
+	}
+
+	/* 5G 20M&40M HT all come from VHT*/
+	if (ht_ref_vht_5g_20_40 && ht_has_ref_5g_20_40 == ht_ref_vht_5g_20_40)
+		pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_HT_FROM_VHT;
+
+	/* 5G 20M&40M VHT all come from HT*/
+	if (vht_ref_ht_5g_20_40 && vht_has_ref_5g_20_40 == vht_ref_ht_5g_20_40)
+		pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_VHT_FROM_HT;
+}
+
+VOID 
+PHY_ConvertTxPowerLimitToPowerIndex(
+	IN	PADAPTER			Adapter
+	)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+	u8 base;
+	u8 regulation, bw, channel, rateSection;
+	s8 tempValue = 0, tempPwrLmt = 0;
+	u8 rfPath = 0;
+
+	if (pHalData->odmpriv.PhyRegPgValueType != PHY_REG_PG_EXACT_VALUE) {
+		rtw_warn_on(1);
+		return;
+	}
+
+	phy_CrossReferenceHTAndVHTTxPowerLimit(Adapter);
+
+	for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
+
+		for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
+
+			for (channel = 0; channel < CENTER_CH_2G_NUM; ++channel) {
+
+				for (rateSection = CCK; rateSection <= HT_4SS; ++rateSection) {
+					tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][RF_PATH_A];
+
+					if (tempPwrLmt != MAX_POWER_INDEX) {
+
+						for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) {
+							base = phy_get_target_tx_power(Adapter, BAND_ON_2_4G, rfPath, rateSection);
+							tempValue = tempPwrLmt - base;
+							pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][rfPath] = tempValue;
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(Adapter)) {
+
+		for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
+
+			for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
+
+				for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
+
+					for (rateSection = OFDM; rateSection <= VHT_4SS; ++rateSection) {
+						tempPwrLmt = pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][RF_PATH_A];
+
+						if (tempPwrLmt != MAX_POWER_INDEX) {
+
+							for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) {
+								base = phy_get_target_tx_power(Adapter, BAND_ON_5G, rfPath, rateSection);
+								tempValue = tempPwrLmt - base;
+								pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][rfPath] = tempValue;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+/*
+* PHY_InitTxPowerLimit - Set all hal_data.TxPwrLimit_2_4G, TxPwrLimit_5G array to MAX_POWER_INDEX
+*/
+VOID
+PHY_InitTxPowerLimit(
+	IN	PADAPTER		Adapter
+	)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+	u8 i, j, k, l, m;
+
+	for (i = 0; i < MAX_REGULATION_NUM; ++i)
+		for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
+			for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
+				for (m = 0; m < CENTER_CH_2G_NUM; ++m)
+					for (l = 0; l < MAX_RF_PATH; ++l)
+						pHalData->TxPwrLimit_2_4G[i][j][k][m][l] = MAX_POWER_INDEX;
+
+	for (i = 0; i < MAX_REGULATION_NUM; ++i)
+		for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
+			for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
+				for (m = 0; m < CENTER_CH_5G_ALL_NUM; ++m)
+					for (l = 0; l < MAX_RF_PATH; ++l)
+						pHalData->TxPwrLimit_5G[i][j][k][m][l] = MAX_POWER_INDEX;
+}
+
+/*
+* PHY_SetTxPowerLimit - Parsing TX power limit from phydm array, called by odm_ConfigBB_TXPWR_LMT_XXX in phydm
+*/
+VOID
+PHY_SetTxPowerLimit(
+	IN	PDM_ODM_T		pDM_Odm,
+	IN	u8				*Regulation,
+	IN	u8				*Band,
+	IN	u8				*Bandwidth,
+	IN	u8				*RateSection,
+	IN	u8				*RfPath,
+	IN	u8				*Channel,
+	IN	u8				*PowerLimit
+	)
+{
+	PADAPTER Adapter = pDM_Odm->Adapter;
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+	u8 regulation = 0, bandwidth = 0, rateSection = 0, channel;
+	s8 powerLimit = 0, prevPowerLimit, channelIndex;
+
+	if (0)
+		DBG_871X("Index of power limit table [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s][val %s]\n"
+			, Band, Regulation, Bandwidth, RateSection, RfPath, Channel, PowerLimit);
+
+	if (GetU1ByteIntegerFromStringInDecimal((s8 *)Channel, &channel) == _FALSE
+		|| GetU1ByteIntegerFromStringInDecimal((s8 *)PowerLimit, &powerLimit) == _FALSE
+	){
+		DBG_871X_LEVEL(_drv_always_, "Illegal index of power limit table [ch %s][val %s]\n", Channel, PowerLimit);
+		return;
+	}
+
+	powerLimit = powerLimit > MAX_POWER_INDEX ? MAX_POWER_INDEX : powerLimit;
+
+	if (eqNByte(Regulation, (u8 *)("FCC"), 3))
+		regulation = TXPWR_LMT_FCC;
+	else if (eqNByte(Regulation, (u8 *)("MKK"), 3))
+		regulation = TXPWR_LMT_MKK;
+	else if (eqNByte(Regulation, (u8 *)("ETSI"), 4))
+		regulation = TXPWR_LMT_ETSI;
+	else if (eqNByte(Regulation, (u8 *)("WW13"), 4))
+		regulation = TXPWR_LMT_WW;
+	else {
+		DBG_871X_LEVEL(_drv_always_, "unknown regulation:%s", Regulation);
+		return;
+	}
+
+	if (eqNByte(RateSection, (u8 *)("CCK"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
+		rateSection = CCK;
+	else if (eqNByte(RateSection, (u8 *)("OFDM"), 4) && eqNByte(RfPath, (u8 *)("1T"), 2))
+		rateSection = OFDM;
+	else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("1T"), 2))
+		rateSection = HT_1SS;
+	else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("2T"), 2))
+		rateSection = HT_2SS;
+	else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("3T"), 2))
+		rateSection = HT_3SS;
+	else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("4T"), 2))
+		rateSection = HT_4SS;
+	else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
+		rateSection = VHT_1SS;
+	else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("2T"), 2))
+		rateSection = VHT_2SS;
+	else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("3T"), 2))
+		rateSection = VHT_3SS;
+	else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("4T"), 2))
+		rateSection = VHT_4SS;
+	else {
+		DBG_871X_LEVEL(_drv_always_, "Wrong rate section: (%s,%s)\n", RateSection, RfPath);
+		return;
+	}
+
+	if (eqNByte(Bandwidth, (u8 *)("20M"), 3))
+		bandwidth = CHANNEL_WIDTH_20;
+	else if (eqNByte(Bandwidth, (u8 *)("40M"), 3))
+		bandwidth = CHANNEL_WIDTH_40;
+	else if (eqNByte(Bandwidth, (u8 *)("80M"), 3))
+		bandwidth = CHANNEL_WIDTH_80;
+	else {
+		DBG_871X_LEVEL(_drv_always_, "unknown bandwidth: %s\n", Bandwidth);
+		return;
+	}
+
+	if (eqNByte(Band, (u8 *)("2.4G"), 4)) {
+		channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel);
+
+		if (channelIndex == -1) {
+			DBG_871X_LEVEL(_drv_always_, "unsupported channel: %d at 2.4G\n", channel);
+			return;
+		}
+
+		if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) {
+			DBG_871X_LEVEL(_drv_always_, "unsupported bandwidth: %s at 2.4G\n", Bandwidth);
+			return;
+		}
+
+		prevPowerLimit = pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
+
+		if (prevPowerLimit != MAX_POWER_INDEX)
+			DBG_871X_LEVEL(_drv_always_, "duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n"
+				, Band, Regulation, Bandwidth, RateSection, RfPath, Channel);
+
+		if (powerLimit < prevPowerLimit)
+			pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
+
+		if (0)
+			DBG_871X("2.4G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n"
+				, regulation, bandwidth, rateSection, channelIndex, pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A]);
+	} else if (eqNByte(Band, (u8 *)("5G"), 2)) {
+
+		channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel);
+
+		if (channelIndex == -1) {
+			DBG_871X_LEVEL(_drv_always_, "unsupported channel: %d at 5G\n", channel);
+			return;
+		}
+
+		prevPowerLimit = pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
+
+		if (prevPowerLimit != MAX_POWER_INDEX)
+			DBG_871X_LEVEL(_drv_always_, "duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n"
+				, Band, Regulation, Bandwidth, RateSection, RfPath, Channel);
+
+		if (powerLimit < prevPowerLimit)
+			pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
+
+		if (0)
+			DBG_871X("5G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n"
+				, regulation, bandwidth, rateSection, channel, pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A]);
+	} else {
+		DBG_871X_LEVEL(_drv_always_, "Cannot recognize the band info in %s\n", Band);
+		return;
+	}
+}
+
+u8
+PHY_GetTxPowerIndex(
+	IN	PADAPTER			pAdapter,
+	IN	u8					RFPath,
+	IN	u8					Rate,	
+	IN	CHANNEL_WIDTH		BandWidth,	
+	IN	u8					Channel
+	)
+{
+	u8	txPower = 0x3E;
+
+	if (IS_HARDWARE_TYPE_8814A(pAdapter)) {
+#if (RTL8814A_SUPPORT == 1)
+		txPower = PHY_GetTxPowerIndex_8814A(pAdapter, RFPath, Rate, BandWidth, Channel);
+#endif
+	} else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) {
+#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
+		txPower = PHY_GetTxPowerIndex_8812A(pAdapter, RFPath, Rate, BandWidth, Channel);
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pAdapter)) {
+#if (RTL8723B_SUPPORT == 1)
+		txPower = PHY_GetTxPowerIndex_8723B(pAdapter, RFPath, Rate, BandWidth, Channel);
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pAdapter)) {
+#if (RTL8703B_SUPPORT == 1)
+		txPower = PHY_GetTxPowerIndex_8703B(pAdapter, RFPath, Rate, BandWidth, Channel);
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pAdapter)) {
+#if (RTL8192E_SUPPORT==1)
+		txPower = PHY_GetTxPowerIndex_8192E(pAdapter, RFPath, Rate, BandWidth, Channel);
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+#if (RTL8188E_SUPPORT==1)
+		txPower = PHY_GetTxPowerIndex_8188E(pAdapter, RFPath, Rate, BandWidth, Channel);
+#endif
+	} else if (IS_HARDWARE_TYPE_8188F(pAdapter)) {
+#if (RTL8188F_SUPPORT == 1)
+		txPower = PHY_GetTxPowerIndex_8188F(pAdapter, RFPath, Rate, BandWidth, Channel);
+#endif
+	}
+
+	return txPower;
+}
+
+VOID
+PHY_SetTxPowerIndex(
+	IN	PADAPTER		pAdapter,
+	IN	u32				PowerIndex,
+	IN	u8				RFPath,	
+	IN	u8				Rate
+	)
+{
+	if (IS_HARDWARE_TYPE_8814A(pAdapter)) {
+#if (RTL8814A_SUPPORT == 1)
+		PHY_SetTxPowerIndex_8814A(pAdapter, PowerIndex, RFPath, Rate);
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) {
+#if ((RTL8812A_SUPPORT==1) || (RTL8821A_SUPPORT == 1))
+		PHY_SetTxPowerIndex_8812A( pAdapter, PowerIndex, RFPath, Rate );
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_8723B(pAdapter)) {
+#if (RTL8723B_SUPPORT==1)
+		PHY_SetTxPowerIndex_8723B( pAdapter, PowerIndex, RFPath, Rate );
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_8703B(pAdapter)) {
+#if (RTL8703B_SUPPORT==1)
+		PHY_SetTxPowerIndex_8703B( pAdapter, PowerIndex, RFPath, Rate );
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_8192E(pAdapter)) {
+#if (RTL8192E_SUPPORT==1)
+		PHY_SetTxPowerIndex_8192E( pAdapter, PowerIndex, RFPath, Rate );
+#endif
+	}
+	else if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+#if (RTL8188E_SUPPORT==1)
+		PHY_SetTxPowerIndex_8188E( pAdapter, PowerIndex, RFPath, Rate );
+#endif
+	} else if (IS_HARDWARE_TYPE_8188F(pAdapter)) {
+#if (RTL8188F_SUPPORT == 1)
+		PHY_SetTxPowerIndex_8188F(pAdapter, PowerIndex, RFPath, Rate);
+#endif
+	}
+}
+
+bool phy_is_tx_power_limit_needed(_adapter *adapter)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+
+	if (regsty->RegEnableTxPowerLimit == 1
+		|| (regsty->RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory == 1))
+		return _TRUE;
+	return _FALSE;
+}
+
+bool phy_is_tx_power_by_rate_needed(_adapter *adapter)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+
+	if (regsty->RegEnableTxPowerByRate == 1
+		|| (regsty->RegEnableTxPowerByRate == 2 && hal_data->EEPROMRegulatory != 2))
+		return _TRUE;
+	return _FALSE;
+}
+
+int phy_load_tx_power_by_rate(_adapter *adapter, const char *hal_file_name, u8 force)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+	int ret = _FAIL;
+
+	if (!force
+		&& !rtw_is_phy_file_readable(hal_file_name)
+		&& hal_data->txpwr_by_rate_loaded == 1
+		&& hal_data->txpwr_by_rate_from_file == 0
+	) {
+		/* No file and already load default(compile-time) table */
+		ret = _SUCCESS;
+		goto exit;
+	}
+
+	hal_data->txpwr_by_rate_loaded = 0;
+	PHY_InitTxPowerByRate(adapter);
+
+	/* tx power limit is based on tx power by rate */
+	hal_data->txpwr_limit_loaded = 0;
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+	if (rtw_is_phy_file_readable(hal_file_name)
+		&& phy_ConfigBBWithPgParaFile(adapter, hal_file_name) == _SUCCESS
+	) {
+		hal_data->txpwr_by_rate_from_file = 1;
+		goto post_hdl;
+	}
+#endif
+
+#ifdef CONFIG_EMBEDDED_FWIMG
+	if (HAL_STATUS_SUCCESS == ODM_ConfigBBWithHeaderFile(&hal_data->odmpriv, CONFIG_BB_PHY_REG_PG)) {
+		DBG_871X("default power by rate loaded\n");
+		hal_data->txpwr_by_rate_from_file = 0;
+		goto post_hdl;
+	}
+#endif
+
+	DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power by rate fail\n", __func__);
+	goto exit;
+
+post_hdl:
+	if (hal_data->odmpriv.PhyRegPgValueType != PHY_REG_PG_EXACT_VALUE) {
+		rtw_warn_on(1);
+		goto exit;
+	}
+
+	PHY_TxPowerByRateConfiguration(adapter);
+	hal_data->txpwr_by_rate_loaded = 1;
+
+	ret = _SUCCESS;
+
+exit:
+	return ret;
+}
+
+int phy_load_tx_power_limit(_adapter *adapter, const char *hal_file_name, u8 force)
+{
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+	int ret = _FAIL;
+
+	if (!force
+		&& !rtw_is_phy_file_readable(hal_file_name)
+		&& hal_data->txpwr_by_rate_loaded == 1
+		&& hal_data->txpwr_by_rate_from_file == 0
+	) {
+		/* No file and already load default(compile-time) table */
+		ret = _SUCCESS;
+		goto exit;
+	}
+
+	hal_data->txpwr_limit_loaded = 0;
+	PHY_InitTxPowerLimit(adapter);
+
+	if (!hal_data->txpwr_by_rate_loaded && regsty->target_tx_pwr_valid != _TRUE) {
+		DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power limit before target tx power is specify\n", __func__);
+		goto exit;
+	}
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+	if (rtw_is_phy_file_readable(hal_file_name)
+		&& PHY_ConfigRFWithPowerLimitTableParaFile(adapter, hal_file_name) == _SUCCESS
+	) {
+		hal_data->txpwr_limit_from_file = 1;
+		goto post_hdl;
+	}
+#endif
+
+#ifdef CONFIG_EMBEDDED_FWIMG
+	if (HAL_STATUS_SUCCESS == ODM_ConfigRFWithHeaderFile(&hal_data->odmpriv, CONFIG_RF_TXPWR_LMT, (ODM_RF_RADIO_PATH_E)0)) {
+		DBG_871X("default power limit loaded\n");
+		hal_data->txpwr_limit_from_file = 0;
+		goto post_hdl;
+	}
+#endif
+
+	DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power limit fail\n", __func__);
+	goto exit;
+
+post_hdl:
+	PHY_ConvertTxPowerLimitToPowerIndex(adapter);
+	hal_data->txpwr_limit_loaded = 1;
+	ret = _SUCCESS;
+
+exit:
+	return ret;
+}
+
+const char *hal_phy_reg_pg_str(_adapter *adapter)
+{
+	u8 interface_type = 0;
+	const char *str = NULL;
+
+	interface_type = rtw_get_intf_type(adapter);
+
+	switch (rtw_get_chip_type(adapter)) {
+#ifdef CONFIG_RTL8723B
+	case RTL8723B:
+		str = RTL8723B_PHY_REG_PG;
+		break;
+#endif
+#ifdef CONFIG_RTL8703B
+	case RTL8703B:
+		str = RTL8703B_PHY_REG_PG;
+		break;
+#endif
+#ifdef CONFIG_RTL8188E
+	case RTL8188E:
+		str = RTL8188E_PHY_REG_PG;
+		break;
+#endif
+#ifdef CONFIG_RTL8188F
+	case RTL8188F:
+		str = RTL8188F_PHY_REG_PG;
+		break;
+#endif
+#ifdef CONFIG_RTL8812A
+	case RTL8812:
+		str = RTL8812_PHY_REG_PG;
+		break;
+#endif
+#ifdef CONFIG_RTL8821A
+	case RTL8821:
+		str = RTL8821_PHY_REG_PG;
+		break;
+#endif
+#ifdef CONFIG_RTL8192E
+	case RTL8192E:
+		str = RTL8192E_PHY_REG_PG;
+		break;
+#endif
+#ifdef CONFIG_RTL8814A
+	case RTL8814A:
+		str = RTL8814A_PHY_REG_PG;
+		break;
+#endif
+	}
+
+	if (str == NULL) {
+		DBG_871X_LEVEL(_drv_err_, "%s: unknown chip_type:%u\n"
+			, __func__, rtw_get_chip_type(adapter));
+	}
+
+	return str;
+}
+
+const char *hal_txpwr_lmt_str(_adapter *adapter)
+{
+	u8 interface_type = 0;
+	const char *str = NULL;
+
+	interface_type = rtw_get_intf_type(adapter);
+
+	switch (rtw_get_chip_type(adapter)) {
+#ifdef CONFIG_RTL8723B
+	case RTL8723B:
+		str = RTL8723B_TXPWR_LMT;
+		break;
+#endif
+#ifdef CONFIG_RTL8703B
+	case RTL8703B:
+		str = RTL8703B_TXPWR_LMT;
+		break;
+#endif
+#ifdef CONFIG_RTL8188E
+	case RTL8188E:
+		str = RTL8188E_TXPWR_LMT;
+		break;
+#endif
+#ifdef CONFIG_RTL8188F
+	case RTL8188F:
+		str = RTL8188F_TXPWR_LMT;
+		break;
+#endif
+#ifdef CONFIG_RTL8812A
+	case RTL8812:
+		str = RTL8812_TXPWR_LMT;
+		break;
+#endif
+#ifdef CONFIG_RTL8821A
+	case RTL8821:
+		str = RTL8821_TXPWR_LMT;
+		break;
+#endif
+#ifdef CONFIG_RTL8192E
+	case RTL8192E:
+		str = RTL8192E_TXPWR_LMT;
+		break;
+#endif
+#ifdef CONFIG_RTL8814A
+	case RTL8814A:
+		str = RTL8814A_TXPWR_LMT;
+		break;
+#endif
+	}
+
+	if (str == NULL) {
+		DBG_871X_LEVEL(_drv_err_, "%s: unknown chip_type:%u\n"
+			, __func__, rtw_get_chip_type(adapter));
+	}
+
+	return str;
+}
+
+void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file, u8 force)
+{
+	struct registry_priv *regsty = adapter_to_regsty(adapter);
+	const char *str = NULL;
+
+	/* check registy target tx power */
+	regsty->target_tx_pwr_valid = rtw_regsty_chk_target_tx_power_valid(adapter);
+
+	/* power by rate and limit */
+	if (phy_is_tx_power_by_rate_needed(adapter)
+		|| (phy_is_tx_power_limit_needed(adapter) && regsty->target_tx_pwr_valid != _TRUE)
+	) {
+		str = chk_file ? hal_phy_reg_pg_str(adapter) : NULL;
+		phy_load_tx_power_by_rate(adapter, str, force);
+	}
+
+	if (phy_is_tx_power_limit_needed(adapter)) {
+		str = chk_file ? hal_txpwr_lmt_str(adapter) : NULL;
+		phy_load_tx_power_limit(adapter, str, force);
+	}
+}
+
+inline void phy_reload_tx_power_ext_info(_adapter *adapter)
+{
+	phy_load_tx_power_ext_info(adapter, 1, 1);
+}
+
+inline void phy_reload_default_tx_power_ext_info(_adapter *adapter)
+{
+	phy_load_tx_power_ext_info(adapter, 0, 1);
+}
+
+void dump_tx_power_ext_info(void *sel, _adapter *adapter)
+{
+	struct registry_priv *regsty = adapter_to_regsty(adapter);
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+	if (phy_is_tx_power_by_rate_needed(adapter)
+		|| (phy_is_tx_power_limit_needed(adapter) && regsty->target_tx_pwr_valid != _TRUE))
+		DBG_871X_SEL_NL(sel, "target_tx_power: from powr by rate\n");
+	else if (regsty->target_tx_pwr_valid == _TRUE)
+		DBG_871X_SEL_NL(sel, "target_tx_power: from registry\n");
+	else
+		DBG_871X_SEL_NL(sel, "target_tx_power: unavailable\n");
+
+
+	DBG_871X_SEL_NL(sel, "tx_power_by_rate: %s, %s, %s\n"
+		, phy_is_tx_power_by_rate_needed(adapter) ? "enabled" : "disabled"
+		, hal_data->txpwr_by_rate_loaded ? "loaded" : "unloaded"
+		, hal_data->txpwr_by_rate_from_file ? "file" : "default"
+	);
+
+	DBG_871X_SEL_NL(sel, "tx_power_limit: %s, %s, %s\n"
+		, phy_is_tx_power_limit_needed(adapter) ? "enabled" : "disabled"
+		, hal_data->txpwr_limit_loaded ? "loaded" : "unloaded"
+		, hal_data->txpwr_limit_from_file ? "file" : "default"
+	);
+}
+
+void dump_target_tx_power(void *sel, _adapter *adapter)
+{
+	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	struct registry_priv *regsty = adapter_to_regsty(adapter);
+	int path, tx_num, band, rs;
+	u8 target;
+
+	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+		if (!hal_is_band_support(adapter, band))
+			continue;
+
+		for (path = 0; path < RF_PATH_MAX; path++) {
+			if (path >= hal_data->NumTotalRFPath)
+				break;
+
+			DBG_871X_SEL_NL(sel, "[%s][%c]\n", band_str(band), rf_path_char(path));
+
+			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+				tx_num = rate_section_to_tx_num(rs);
+				if (tx_num >= hal_spec->nss_num)
+					continue;
+
+				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+					continue;
+
+				if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
+					continue;
+
+				target = phy_get_target_tx_power(adapter, band, path, rs);
+
+				if (target % 2)
+					DBG_871X_SEL(sel, "%7s: %2d.5\n", rate_section_str(rs), target / 2);
+				else
+					DBG_871X_SEL(sel, "%7s: %4d\n", rate_section_str(rs), target / 2);
+			}
+		}
+	}
+
+exit:
+	return;
+}
+
+void dump_tx_power_by_rate(void *sel, _adapter *adapter)
+{
+	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	int path, tx_num, band, n, rs;
+	u8 rate_num, max_rate_num, base;
+	s8 by_rate_offset;
+
+	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+		if (!hal_is_band_support(adapter, band))
+			continue;
+
+		for (path = 0; path < RF_PATH_MAX; path++) {
+			if (path >= hal_data->NumTotalRFPath)
+				break;
+
+			DBG_871X_SEL_NL(sel, "[%s][%c]\n", band_str(band), rf_path_char(path));
+
+			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+				tx_num = rate_section_to_tx_num(rs);
+				if (tx_num >= hal_spec->nss_num)
+					continue;
+
+				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+					continue;
+
+				if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
+					continue;
+
+				if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
+					max_rate_num = 10;
+				else
+					max_rate_num = 8;
+				rate_num = rate_section_rate_num(rs);
+				base = PHY_GetTxPowerByRateBase(adapter, band, path, tx_num, rs);
+
+				DBG_871X_SEL_NL(sel, "%7s: ", rate_section_str(rs));
+
+				/* dump power by rate in db */
+				for (n = rate_num - 1; n >= 0; n--) {
+					by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]);
+
+					if ((base + by_rate_offset) % 2)
+						DBG_871X_SEL(sel, "%2d.5 ", (base + by_rate_offset) / 2);
+					else
+						DBG_871X_SEL(sel, "%4d ", (base + by_rate_offset) / 2);
+				}
+				for (n = 0; n < max_rate_num - rate_num; n++)
+					DBG_871X_SEL(sel, "%4s ", "");
+
+				DBG_871X_SEL(sel, "|");
+
+				/* dump power by rate in offset */
+				for (n = rate_num - 1; n >= 0; n--) {
+					by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]);
+					DBG_871X_SEL(sel, "%3d ", by_rate_offset);
+				}
+				DBG_871X_SEL_NL(sel, "\n");
+
+			}
+		}
+	}
+}
+
+void dump_tx_power_limit(void *sel, _adapter *adapter)
+{
+	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+
+	int bw, band, ch_num, rs, i, path;
+	u8 ch, n, rd;
+
+	if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
+		DBG_871X_SEL_NL(sel, "tx_pwr_lmt_5g_20_40_ref:0x%02x\n", hal_data->tx_pwr_lmt_5g_20_40_ref);
+
+	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+		if (!hal_is_band_support(adapter, band))
+			continue;
+
+		rd = (band == BAND_ON_2_4G ? hal_data->Regulation2_4G : hal_data->Regulation5G);
+
+		for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; bw++) {
+
+			if (bw >= CHANNEL_WIDTH_160)
+				break;
+			if (band == BAND_ON_2_4G && bw >= CHANNEL_WIDTH_80)
+				break;
+
+			if (band == BAND_ON_2_4G)
+				ch_num = CENTER_CH_2G_NUM;
+			else
+				ch_num = center_chs_5g_num(bw);
+
+			if (ch_num == 0) {
+				rtw_warn_on(1);
+				break;
+			}
+
+			for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+				if (band == BAND_ON_2_4G && IS_VHT_RATE_SECTION(rs))
+					continue;
+				if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+					continue;
+				if (bw > CHANNEL_WIDTH_20 && (IS_CCK_RATE_SECTION(rs) || IS_OFDM_RATE_SECTION(rs)))
+					continue;
+				if (bw > CHANNEL_WIDTH_40 && IS_HT_RATE_SECTION(rs))
+					continue;
+
+				if (rate_section_to_tx_num(rs) >= hal_spec->nss_num)
+					continue;
+
+				if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter))
+					continue;
+
+				/* by pass 5G 20M, 40M pure reference */
+				if (band == BAND_ON_5G && (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40)) {
+					if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_HT_FROM_VHT) {
+						if (IS_HT_RATE_SECTION(rs))
+							continue;
+					} else if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_VHT_FROM_HT) {
+						if (IS_VHT_RATE_SECTION(rs) && bw <= CHANNEL_WIDTH_40)
+							continue;
+					}
+				}
+
+				DBG_871X_SEL_NL(sel, "[%s][%s][%s]\n"
+					, band_str(band)
+					, ch_width_str(bw)
+					, rate_section_str(rs)
+				);
+
+				/* header for limit in db */
+				DBG_871X_SEL_NL(sel, "%3s %5s %5s %5s %5s "
+					, "ch"
+					, (rd == TXPWR_LMT_FCC ? "*FCC" : "FCC")
+					, (rd == TXPWR_LMT_ETSI ? "*ETSI" : "ETSI")
+					, (rd == TXPWR_LMT_MKK ? "*MKK" : "MKK")
+					, (rd == TXPWR_LMT_WW ? "*WW" : "WW")
+				);
+
+				/* header for limit offset */
+				for (path = 0; path < RF_PATH_MAX; path++) {
+					if (path >= hal_data->NumTotalRFPath)
+						break;
+					DBG_871X_SEL(sel, "|%3c %3c %3c %3c "
+						, (rd == TXPWR_LMT_FCC ? rf_path_char(path) : ' ')
+						, (rd == TXPWR_LMT_ETSI ? rf_path_char(path) : ' ')
+						, (rd == TXPWR_LMT_MKK ? rf_path_char(path) : ' ')
+						, (rd == TXPWR_LMT_WW ? rf_path_char(path) : ' ')
+					);
+				}
+				DBG_871X_SEL(sel, "\n");
+
+				for (n = 0; n < ch_num; n++) {
+					s8 limit_idx[RF_PATH_MAX][MAX_REGULATION_NUM];
+					s8 limit_offset[MAX_REGULATION_NUM];
+					u8 base;
+
+					if (band == BAND_ON_2_4G)
+						ch = n + 1;
+					else
+						ch = center_chs_5g(bw, n);
+
+					if (ch == 0) {
+						rtw_warn_on(1);
+						break;
+					}
+
+					/* dump limit in db (calculate from path A) */
+					limit_offset[0] = PHY_GetTxPowerLimit(adapter, 3, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* FCC */
+					limit_offset[1] = PHY_GetTxPowerLimit(adapter, 1, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* ETSI */
+					limit_offset[2] = PHY_GetTxPowerLimit(adapter, 2, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* MKK */
+					limit_offset[3] = PHY_GetTxPowerLimit(adapter, 4, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* WW */
+
+					base = phy_get_target_tx_power(adapter, band, RF_PATH_A, rs);
+
+					DBG_871X_SEL_NL(sel, "%3u ", ch);
+					for (i = 0; i < MAX_REGULATION_NUM; i++) {
+						if (limit_offset[i] == MAX_POWER_INDEX) {
+							limit_idx[0][i] = MAX_POWER_INDEX;
+							DBG_871X_SEL(sel, "%5s ", "NA");
+						} else {
+							limit_idx[0][i] = limit_offset[i] + base;
+							if ((limit_offset[i] + base) % 2)
+								DBG_871X_SEL(sel, "%3d.5 ", (limit_offset[i] + base) / 2);
+							else
+								DBG_871X_SEL(sel, "%5d ", (limit_offset[i] + base) / 2);
+						}
+					}
+
+					/* dump limit offset of each path */
+					for (path = 0; path < RF_PATH_MAX; path++) {
+						if (path >= hal_data->NumTotalRFPath)
+							break;
+						limit_offset[0] = PHY_GetTxPowerLimit(adapter, 3, band, bw, path, rates_by_sections[rs].rates[0], ch); /* FCC */
+						limit_offset[1] = PHY_GetTxPowerLimit(adapter, 1, band, bw, path, rates_by_sections[rs].rates[0], ch); /* ETSI */
+						limit_offset[2] = PHY_GetTxPowerLimit(adapter, 2, band, bw, path, rates_by_sections[rs].rates[0], ch); /* MKK */
+						limit_offset[3] = PHY_GetTxPowerLimit(adapter, 4, band, bw, path, rates_by_sections[rs].rates[0], ch); /* WW */
+
+						base = phy_get_target_tx_power(adapter, band, path, rs);
+
+						DBG_871X_SEL(sel, "|");
+						for (i = 0; i < MAX_REGULATION_NUM; i++) {
+							if (limit_offset[i] == MAX_POWER_INDEX) {
+								limit_idx[path][i] = MAX_POWER_INDEX;
+								DBG_871X_SEL(sel, "%3s ", "NA");
+							} else {
+								limit_idx[path][i] = limit_offset[i] + base;
+								DBG_871X_SEL(sel, "%3d ", limit_offset[i]);
+							}
+						}
+					}
+
+					/* compare limit_idx of each path, print 'x' when mismatch */
+					if (hal_data->NumTotalRFPath > 1) {
+						for (i = 0; i < MAX_REGULATION_NUM; i++) {
+							for (path = 0; path < RF_PATH_MAX; path++) {
+								if (path >= hal_data->NumTotalRFPath)
+									break;
+								if (limit_idx[path][i] != limit_idx[(path + 1) % hal_data->NumTotalRFPath][i])
+									break;
+							}
+							if (path >= hal_data->NumTotalRFPath)
+								DBG_871X_SEL(sel, " ");
+							else
+								DBG_871X_SEL(sel, "x");
+						}
+					}
+					DBG_871X_SEL(sel, "\n");
+
+				}
+				DBG_871X_SEL_NL(sel, "\n");
+			}
+		}
+	}
+}
+
+int rtw_is_phy_file_readable(const char *hal_file_name)
+{
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+	if (hal_file_name) {
+		rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, hal_file_name);
+		return rtw_is_file_readable(file__path);
+	}
+#endif
+	return _FALSE;
+}
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+int
+phy_ConfigMACWithParaFile(
+	IN	PADAPTER	Adapter,
+	IN	char* 		pFileName
+)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	int	rlen = 0, rtStatus = _FAIL;
+	char	*szLine, *ptmp;
+	u32	u4bRegOffset, u4bRegValue, u4bMove;
+
+	if(!(Adapter->registrypriv.load_phy_file & LOAD_MAC_PARA_FILE))
+		return rtStatus;
+
+	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+	if ((pHalData->mac_reg_len == 0) && (pHalData->mac_reg == NULL))
+	{
+		rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
+	
+		if (rtw_is_file_readable(file__path) == _TRUE)
+		{
+			rlen = rtw_retrieve_from_file(file__path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+			if (rlen > 0)
+			{
+				rtStatus = _SUCCESS;
+				pHalData->mac_reg = rtw_zvmalloc(rlen);
+				if(pHalData->mac_reg) {
+					_rtw_memcpy(pHalData->mac_reg, pHalData->para_file_buf, rlen);
+					pHalData->mac_reg_len = rlen;
+				}
+				else {
+					DBG_871X("%s mac_reg alloc fail !\n",__FUNCTION__);
+				}
+			}
+		}
+	}
+	else
+	{
+		if ((pHalData->mac_reg_len != 0) && (pHalData->mac_reg != NULL)) {
+			_rtw_memcpy(pHalData->para_file_buf, pHalData->mac_reg, pHalData->mac_reg_len);
+			rtStatus = _SUCCESS;
+		}
+		else {
+			DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
+		}
+	}
+
+	if (rtStatus == _SUCCESS)
+	{
+		ptmp = pHalData->para_file_buf;
+		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
+		{
+			if(!IsCommentString(szLine))
+			{
+				// Get 1st hex value as register offset
+				if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
+				{
+					if(u4bRegOffset == 0xffff)
+					{ // Ending.
+						break;
+					}
+
+					// Get 2nd hex value as register value.
+					szLine += u4bMove;
+					if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
+					{
+						rtw_write8(Adapter, u4bRegOffset, (u8)u4bRegValue);
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
+	}
+
+	return rtStatus;
+}
+
+int
+phy_ConfigBBWithParaFile(
+	IN	PADAPTER	Adapter,
+	IN	char*		pFileName,
+	IN	u32			ConfigType
+)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	int	rlen = 0, rtStatus = _FAIL;
+	char	*szLine, *ptmp;
+	u32	u4bRegOffset, u4bRegValue, u4bMove;
+	char	*pBuf = NULL;
+	u32	*pBufLen = NULL;
+
+	if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_PARA_FILE))
+		return rtStatus;
+
+	switch(ConfigType)
+	{
+		case CONFIG_BB_PHY_REG:
+			pBuf = pHalData->bb_phy_reg;
+			pBufLen = &pHalData->bb_phy_reg_len;
+			break;
+		case CONFIG_BB_AGC_TAB:
+			pBuf = pHalData->bb_agc_tab;
+			pBufLen = &pHalData->bb_agc_tab_len;
+			break;
+		default:
+			DBG_871X("Unknown ConfigType!! %d\r\n", ConfigType);
+			break;
+	}
+
+	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+	if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL))
+	{
+		rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
+	
+		if (rtw_is_file_readable(file__path) == _TRUE)
+		{
+			rlen = rtw_retrieve_from_file(file__path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+			if (rlen > 0)
+			{
+				rtStatus = _SUCCESS;
+				pBuf = rtw_zvmalloc(rlen);
+				if(pBuf) {
+					_rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
+					*pBufLen = rlen;
+
+					switch(ConfigType)
+					{
+						case CONFIG_BB_PHY_REG:
+							pHalData->bb_phy_reg = pBuf;
+							break;
+						case CONFIG_BB_AGC_TAB:
+							pHalData->bb_agc_tab = pBuf;
+							break;
+					}
+				}
+				else {
+					DBG_871X("%s(): ConfigType %d  alloc fail !\n",__FUNCTION__,ConfigType);
+				}
+			}
+		}
+	}
+	else
+	{
+		if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
+			_rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
+			rtStatus = _SUCCESS;
+		}
+		else {
+			DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
+		}
+	}
+
+	if (rtStatus == _SUCCESS)
+	{
+		ptmp = pHalData->para_file_buf;
+		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
+		{
+			if(!IsCommentString(szLine))
+			{
+				// Get 1st hex value as register offset.
+				if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
+				{
+					if(u4bRegOffset == 0xffff)
+					{ // Ending.
+						break;
+					}
+					else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe)
+					{
+						#ifdef CONFIG_LONG_DELAY_ISSUE
+						rtw_msleep_os(50);
+						#else
+						rtw_mdelay_os(50);
+						#endif
+					}
+					else if (u4bRegOffset == 0xfd)
+					{
+						rtw_mdelay_os(5);
+					}
+					else if (u4bRegOffset == 0xfc)
+					{
+						rtw_mdelay_os(1);
+					}
+					else if (u4bRegOffset == 0xfb)
+					{
+						rtw_udelay_os(50);
+					}
+					else if (u4bRegOffset == 0xfa)
+					{
+						rtw_udelay_os(5);
+					}
+					else if (u4bRegOffset == 0xf9)
+					{
+						rtw_udelay_os(1);
+					}
+					
+					// Get 2nd hex value as register value.
+					szLine += u4bMove;
+					if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
+					{
+						//DBG_871X("[BB-ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue);
+						PHY_SetBBReg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
+
+						if (u4bRegOffset == 0xa24)
+							pHalData->odmpriv.RFCalibrateInfo.RegA24 = u4bRegValue;
+
+						// Add 1us delay between BB/RF register setting.
+						rtw_udelay_os(1);
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
+	}
+
+	return rtStatus;
+}
+
+VOID
+phy_DecryptBBPgParaFile(
+	PADAPTER		Adapter,
+	char*			buffer
+	)
+{
+	u32	i = 0, j = 0;
+	u8	map[95] = {0};
+	u8	currentChar;
+	char	*BufOfLines, *ptmp;
+
+	//DBG_871X("=====>phy_DecryptBBPgParaFile()\n");
+	// 32 the ascii code of the first visable char, 126 the last one
+	for ( i = 0; i < 95; ++i )
+		map[i] = ( u8 ) ( 94 - i );
+
+	ptmp = buffer;
+	i = 0;
+	for (BufOfLines = GetLineFromBuffer(ptmp); BufOfLines != NULL; BufOfLines = GetLineFromBuffer(ptmp))
+	{
+		//DBG_871X("Encrypted Line: %s\n", BufOfLines);
+
+		for ( j = 0; j < strlen(BufOfLines); ++j )
+		{
+			currentChar = BufOfLines[j];
+
+			if ( currentChar == '\0' )
+				break;
+
+			currentChar -=  (u8) ( ( ( ( i + j ) * 3 ) % 128 ) );
+			
+			BufOfLines[j] = map[currentChar - 32] + 32;
+		}
+		//DBG_871X("Decrypted Line: %s\n", BufOfLines );
+		if (strlen(BufOfLines) != 0)
+			i++;
+		BufOfLines[strlen(BufOfLines)] = '\n';
+	}
+}
+
+int
+phy_ParseBBPgParaFile(
+	PADAPTER		Adapter,
+	char*			buffer
+	)
+{
+	int	rtStatus = _SUCCESS;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	char	*szLine, *ptmp;
+	u32	u4bRegOffset, u4bRegMask, u4bRegValue;
+	u32	u4bMove;
+	BOOLEAN firstLine = _TRUE;
+	u8	tx_num = 0;
+	u8	band = 0, rf_path = 0;
+
+	//DBG_871X("=====>phy_ParseBBPgParaFile()\n");
+	
+	if ( Adapter->registrypriv.RegDecryptCustomFile == 1 )
+		phy_DecryptBBPgParaFile( Adapter, buffer);
+
+	ptmp = buffer;
+	for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
+	{
+		if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
+			continue;
+
+		if(!IsCommentString(szLine))
+		{
+			// Get header info (relative value or exact value)
+			if ( firstLine )
+			{
+				if ( eqNByte( szLine, (u8 *)("#[v1]"), 5 ) )
+				{
+					
+					pHalData->odmpriv.PhyRegPgVersion = szLine[3] - '0';
+					//DBG_871X("This is a new format PHY_REG_PG.txt \n");
+				}
+				else if ( eqNByte( szLine, (u8 *)("#[v0]"), 5 ))
+				{
+					pHalData->odmpriv.PhyRegPgVersion = szLine[3] - '0';
+					//DBG_871X("This is a old format PHY_REG_PG.txt ok\n");
+				}
+				else
+				{
+					DBG_871X("The format in PHY_REG_PG are invalid %s\n", szLine);
+					return _FAIL;
+				}
+					
+				if ( eqNByte( szLine + 5, (u8 *)("[Exact]#"), 8 ) )
+				{
+					pHalData->odmpriv.PhyRegPgValueType = PHY_REG_PG_EXACT_VALUE;
+					//DBG_871X("The values in PHY_REG_PG are exact values ok\n");
+					firstLine = _FALSE;
+					continue;
+				}
+				else if ( eqNByte( szLine + 5, (pu1Byte)("[Relative]#"), 11 ) )
+				{
+					pHalData->odmpriv.PhyRegPgValueType = PHY_REG_PG_RELATIVE_VALUE;
+					//DBG_871X("The values in PHY_REG_PG are relative values ok\n");
+					firstLine = _FALSE;
+					continue;
+				}
+				else
+				{
+					DBG_871X("The values in PHY_REG_PG are invalid %s\n", szLine);
+					return _FAIL;
+				}
+			}
+
+			if ( pHalData->odmpriv.PhyRegPgVersion == 0 )
+			{
+				// Get 1st hex value as register offset.
+				if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
+				{
+					szLine += u4bMove;
+					if(u4bRegOffset == 0xffff)
+					{ // Ending.
+						break;
+					}
+
+					// Get 2nd hex value as register mask.
+					if ( GetHexValueFromString(szLine, &u4bRegMask, &u4bMove) )
+						szLine += u4bMove;
+					else
+						return _FAIL;
+
+					if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_RELATIVE_VALUE ) 
+					{
+						// Get 3rd hex value as register value.
+						if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
+						{
+							PHY_StoreTxPowerByRate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, u4bRegValue);
+							//DBG_871X("[ADDR] %03X=%08X Mask=%08x\n", u4bRegOffset, u4bRegValue, u4bRegMask);
+						}
+						else
+						{
+							return _FAIL;
+						}
+					}
+					else if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE ) 
+					{
+						u32	combineValue = 0;
+						u8	integer = 0, fraction = 0;
+						
+						if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
+							szLine += u4bMove;
+						else 
+							return _FAIL;
+						
+						integer *= 2;
+						if ( fraction == 5 ) integer += 1;
+						combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
+						//DBG_871X(" %d", integer );
+
+						if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
+							szLine += u4bMove;
+						else 
+							return _FAIL;
+
+						integer *= 2;
+						if ( fraction == 5 ) integer += 1;
+						combineValue <<= 8;
+						combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
+						//DBG_871X(" %d", integer );
+
+						if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
+							szLine += u4bMove;
+						else
+							return _FAIL;
+						
+						integer *= 2;
+						if ( fraction == 5 ) integer += 1;
+						combineValue <<= 8;
+						combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
+						//DBG_871X(" %d", integer );
+
+						if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
+							szLine += u4bMove;
+						else 
+							return _FAIL;
+
+						integer *= 2;
+						if ( fraction == 5 ) integer += 1;
+						combineValue <<= 8;
+						combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
+						//DBG_871X(" %d", integer );
+						PHY_StoreTxPowerByRate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, combineValue);
+
+						//DBG_871X("[ADDR] 0x%3x = 0x%4x\n", u4bRegOffset, combineValue );
+					}
+				}
+			}
+			else if ( pHalData->odmpriv.PhyRegPgVersion > 0 )
+			{
+				u32	index = 0, cnt = 0;
+
+				if ( eqNByte( szLine, "0xffff", 6 ) )
+					break;
+
+				if( !eqNByte( "#[END]#", szLine, 7 ) )
+				{
+					// load the table label info
+					if ( szLine[0] == '#' )
+					{
+						index = 0;
+						if ( eqNByte( szLine, "#[2.4G]" , 7 ) )
+						{
+							band = BAND_ON_2_4G;
+							index += 8;
+						}
+						else if ( eqNByte( szLine, "#[5G]", 5) )
+						{
+							band = BAND_ON_5G;
+							index += 6;
+						}
+						else
+						{
+							DBG_871X("Invalid band %s in PHY_REG_PG.txt \n", szLine );
+							return _FAIL;
+						}
+
+						rf_path= szLine[index] - 'A';
+						//DBG_871X(" Table label Band %d, RfPath %d\n", band, rf_path );
+					}
+					else // load rows of tables
+					{
+						if ( szLine[1] == '1' )
+							tx_num = RF_1TX;
+						else if ( szLine[1] == '2' )
+							tx_num = RF_2TX;
+						else if ( szLine[1] == '3' )
+							tx_num = RF_3TX;
+						else if ( szLine[1] == '4' )
+							tx_num = RF_4TX;
+						else
+						{
+							DBG_871X("Invalid row in PHY_REG_PG.txt '%c'(%d)\n", szLine[1], szLine[1]);
+							return _FAIL;
+						}
+
+						while ( szLine[index] != ']' )
+							++index;
+						++index;// skip ]
+
+						// Get 2nd hex value as register offset.
+						szLine += index;
+						if ( GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove) )
+							szLine += u4bMove;
+						else
+							return _FAIL;
+
+						// Get 2nd hex value as register mask.
+						if ( GetHexValueFromString(szLine, &u4bRegMask, &u4bMove) )
+							szLine += u4bMove;
+						else
+							return _FAIL;
+
+						if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_RELATIVE_VALUE ) 
+						{
+							// Get 3rd hex value as register value.
+							if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
+							{
+								PHY_StoreTxPowerByRate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, u4bRegValue);
+								//DBG_871X("[ADDR] %03X (tx_num %d) =%08X Mask=%08x\n", u4bRegOffset, tx_num, u4bRegValue, u4bRegMask);
+							}
+							else
+							{
+								return _FAIL;
+							}
+						}
+						else if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE ) 
+						{
+							u32	combineValue = 0;
+							u8	integer = 0, fraction = 0;
+
+							if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
+								szLine += u4bMove;
+							else
+								return _FAIL;
+
+							integer *= 2;
+							if ( fraction == 5 ) integer += 1;
+							combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
+							//DBG_871X(" %d", integer );
+
+							if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
+								szLine += u4bMove;
+							else
+								return _FAIL;
+
+							integer *= 2;
+							if ( fraction == 5 ) integer += 1;
+							combineValue <<= 8;
+							combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
+							//DBG_871X(" %d", integer );
+
+							if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
+								szLine += u4bMove;
+							else
+								return _FAIL;
+
+							integer *= 2;
+							if ( fraction == 5 ) integer += 1;
+							combineValue <<= 8;
+							combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
+							//DBG_871X(" %d", integer );
+
+							if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) )
+								szLine += u4bMove;
+							else
+								return _FAIL;
+
+							integer *= 2;
+							if ( fraction == 5 ) integer += 1;
+							combineValue <<= 8;
+							combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) );
+							//DBG_871X(" %d", integer );
+							PHY_StoreTxPowerByRate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, combineValue);
+
+							//DBG_871X("[ADDR] 0x%3x (tx_num %d) = 0x%4x\n", u4bRegOffset, tx_num, combineValue );
+						}
+					}
+				}
+			}
+		}
+	}
+	//DBG_871X("<=====phy_ParseBBPgParaFile()\n");
+	return rtStatus;
+}
+
+int
+phy_ConfigBBWithPgParaFile(
+	IN	PADAPTER	Adapter,
+	IN	const char	*pFileName)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	int	rlen = 0, rtStatus = _FAIL;
+
+	if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_PG_PARA_FILE))
+		return rtStatus;
+
+	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+	if (pHalData->bb_phy_reg_pg == NULL) {
+		rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
+	
+		if (rtw_is_file_readable(file__path) == _TRUE)
+		{
+			rlen = rtw_retrieve_from_file(file__path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+			if (rlen > 0)
+			{
+				rtStatus = _SUCCESS;
+				pHalData->bb_phy_reg_pg = rtw_zvmalloc(rlen);
+				if(pHalData->bb_phy_reg_pg) {
+					_rtw_memcpy(pHalData->bb_phy_reg_pg, pHalData->para_file_buf, rlen);
+					pHalData->bb_phy_reg_pg_len = rlen;
+				}
+				else {
+					DBG_871X("%s bb_phy_reg_pg alloc fail !\n",__FUNCTION__);
+				}
+			}
+		}
+	} else {
+		if ((pHalData->bb_phy_reg_pg_len != 0) && (pHalData->bb_phy_reg_pg != NULL)) {
+			_rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
+			rtStatus = _SUCCESS;
+		}
+		else {
+			DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
+		}
+	}
+
+	if(rtStatus == _SUCCESS)
+	{
+		//DBG_871X("phy_ConfigBBWithPgParaFile(): read %s ok\n", pFileName);
+		phy_ParseBBPgParaFile(Adapter, pHalData->para_file_buf);
+	}
+	else
+	{
+		DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
+	}
+
+	return rtStatus;
+}
+
+#if (MP_DRIVER == 1 )
+
+int
+phy_ConfigBBWithMpParaFile(
+	IN	PADAPTER	Adapter,
+	IN	char* 		pFileName
+)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	int	rlen = 0, rtStatus = _FAIL;
+	char	*szLine, *ptmp;
+	u32	u4bRegOffset, u4bRegValue, u4bMove;
+
+	if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_MP_PARA_FILE))
+		return rtStatus;
+
+	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+	if ((pHalData->bb_phy_reg_mp_len == 0) && (pHalData->bb_phy_reg_mp == NULL))
+	{
+		rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
+	
+		if (rtw_is_file_readable(file__path) == _TRUE)
+		{
+			rlen = rtw_retrieve_from_file(file__path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+			if (rlen > 0)
+			{
+				rtStatus = _SUCCESS;
+				pHalData->bb_phy_reg_mp = rtw_zvmalloc(rlen);
+				if(pHalData->bb_phy_reg_mp) {
+					_rtw_memcpy(pHalData->bb_phy_reg_mp, pHalData->para_file_buf, rlen);
+					pHalData->bb_phy_reg_mp_len = rlen;
+				}
+				else {
+					DBG_871X("%s bb_phy_reg_mp alloc fail !\n",__FUNCTION__);
+				}
+			}
+		}
+	}
+	else
+	{
+		if ((pHalData->bb_phy_reg_mp_len != 0) && (pHalData->bb_phy_reg_mp != NULL)) {
+			_rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
+			rtStatus = _SUCCESS;
+		}
+		else {
+			DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
+		}
+	}
+
+	if(rtStatus == _SUCCESS)
+	{
+		//DBG_871X("phy_ConfigBBWithMpParaFile(): read %s ok\n", pFileName);
+
+		ptmp = pHalData->para_file_buf;
+		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
+		{
+			if(!IsCommentString(szLine))
+			{
+				// Get 1st hex value as register offset.
+				if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
+				{
+					if(u4bRegOffset == 0xffff)
+					{ // Ending.
+						break;
+					}
+					else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe)
+					{
+						#ifdef CONFIG_LONG_DELAY_ISSUE
+						rtw_msleep_os(50);
+						#else
+						rtw_mdelay_os(50);
+						#endif
+					}
+					else if (u4bRegOffset == 0xfd)
+					{
+						rtw_mdelay_os(5);
+					}
+					else if (u4bRegOffset == 0xfc)
+					{
+						rtw_mdelay_os(1);
+					}
+					else if (u4bRegOffset == 0xfb)
+					{
+						rtw_udelay_os(50);
+					}
+					else if (u4bRegOffset == 0xfa)
+					{
+						rtw_udelay_os(5);
+					}
+					else if (u4bRegOffset == 0xf9)
+					{
+						rtw_udelay_os(1);
+					}
+
+					// Get 2nd hex value as register value.
+					szLine += u4bMove;
+					if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
+					{
+						//DBG_871X("[ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue);
+						PHY_SetBBReg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
+
+						// Add 1us delay between BB/RF register setting.
+						rtw_udelay_os(1);
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
+	}
+
+	return rtStatus;
+}
+
+#endif
+
+int
+PHY_ConfigRFWithParaFile(
+	IN	PADAPTER	Adapter,
+	IN	char* 		pFileName,
+	IN	u8			eRFPath
+)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	int	rlen = 0, rtStatus = _FAIL;
+	char	*szLine, *ptmp;
+	u32	u4bRegOffset, u4bRegValue, u4bMove;
+	u16	i;
+	char	*pBuf = NULL;
+	u32	*pBufLen = NULL;
+
+	if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_PARA_FILE))
+		return rtStatus;
+
+	switch(eRFPath)
+	{
+		case ODM_RF_PATH_A:
+			pBuf = pHalData->rf_radio_a;
+			pBufLen = &pHalData->rf_radio_a_len;
+			break;
+		case ODM_RF_PATH_B:
+			pBuf = pHalData->rf_radio_b;
+			pBufLen = &pHalData->rf_radio_b_len;
+			break;
+		default:
+			DBG_871X("Unknown RF path!! %d\r\n", eRFPath);
+			break;			
+	}
+
+	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+	if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL))
+	{
+		rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
+
+		if (rtw_is_file_readable(file__path) == _TRUE)
+		{
+			rlen = rtw_retrieve_from_file(file__path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+			if (rlen > 0)
+			{
+				rtStatus = _SUCCESS;
+				pBuf = rtw_zvmalloc(rlen);
+				if(pBuf) {
+					_rtw_memcpy(pBuf, pHalData->para_file_buf, rlen);
+					*pBufLen = rlen;
+
+					switch(eRFPath)
+					{
+						case ODM_RF_PATH_A:
+							pHalData->rf_radio_a = pBuf;
+							break;
+						case ODM_RF_PATH_B:
+							pHalData->rf_radio_b = pBuf;
+							break;
+					}
+				}
+				else {
+					DBG_871X("%s(): eRFPath=%d  alloc fail !\n",__FUNCTION__,eRFPath);
+				}
+			}
+		}
+	}
+	else
+	{
+		if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
+			_rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
+			rtStatus = _SUCCESS;
+		}
+		else {
+			DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
+		}
+	}
+
+	if(rtStatus == _SUCCESS)
+	{
+		//DBG_871X("%s(): read %s successfully\n", __FUNCTION__, pFileName);
+	
+		ptmp = pHalData->para_file_buf;
+		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
+		{
+			if(!IsCommentString(szLine))
+			{
+				// Get 1st hex value as register offset.
+				if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
+				{
+			 		if(u4bRegOffset == 0xfe || u4bRegOffset == 0xffe)
+					{ // Deay specific ms. Only RF configuration require delay.												
+						#ifdef CONFIG_LONG_DELAY_ISSUE
+						rtw_msleep_os(50);
+						#else
+						rtw_mdelay_os(50);
+						#endif
+					}
+					else if (u4bRegOffset == 0xfd)
+					{
+						//delay_ms(5);
+						for(i=0;i<100;i++)
+							rtw_udelay_os(MAX_STALL_TIME);
+					}
+					else if (u4bRegOffset == 0xfc)
+					{
+						//delay_ms(1);
+						for(i=0;i<20;i++)
+							rtw_udelay_os(MAX_STALL_TIME);
+					}
+					else if (u4bRegOffset == 0xfb)
+					{
+						rtw_udelay_os(50);
+					}
+					else if (u4bRegOffset == 0xfa)
+					{
+						rtw_udelay_os(5);
+					}
+					else if (u4bRegOffset == 0xf9)
+					{
+						rtw_udelay_os(1);
+					}
+					else if(u4bRegOffset == 0xffff)
+					{
+						break;					
+					}
+					
+					// Get 2nd hex value as register value.
+					szLine += u4bMove;
+					if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
+					{
+						PHY_SetRFReg(Adapter, eRFPath, u4bRegOffset, bRFRegOffsetMask, u4bRegValue);
+						
+						// Temp add, for frequency lock, if no delay, that may cause
+						// frequency shift, ex: 2412MHz => 2417MHz
+						// If frequency shift, the following action may works.
+						// Fractional-N table in radio_a.txt 
+						//0x2a 0x00001		// channel 1
+						//0x2b 0x00808		frequency divider.
+						//0x2b 0x53333
+						//0x2c 0x0000c
+						rtw_udelay_os(1);
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
+	}
+
+	return rtStatus;
+}
+
+VOID
+initDeltaSwingIndexTables(
+	PADAPTER	Adapter, 
+	char*		Band, 
+	char*		Path,
+	char*		Sign,
+	char*		Channel, 
+	char*		Rate,
+	char*		Data
+)
+{
+	#define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \
+		((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
+		(strcmp(Rate, _rate) == 0) && (strcmp(Channel, _chnl) == 0)\
+	)
+	#define STR_EQUAL_2G(_band, _path, _sign, _rate) \
+		((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
+		(strcmp(Rate, _rate) == 0)\
+	)
+	
+	#define STORE_SWING_TABLE(_array, _iteratedIdx) \
+		for(token = strsep(&Data, delim); token != NULL; token = strsep(&Data, delim))\
+		{\
+			sscanf(token, "%d", &idx);\
+			_array[_iteratedIdx++] = (u8)idx;\
+		}\
+
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
+	PODM_RF_CAL_T  	pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
+	u32	j = 0;
+	char	*token;
+	char	delim[] = ",";
+	u32	idx = 0;
+	
+	//DBG_871X("===>initDeltaSwingIndexTables(): Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n", 
+	//	Band, Path, Sign, Channel, Rate, Data);
+	
+	if ( STR_EQUAL_2G("2G", "A", "+", "CCK") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P, j);
+	}
+	else if ( STR_EQUAL_2G("2G", "A", "-", "CCK") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N, j);
+	}
+	else if ( STR_EQUAL_2G("2G", "B", "+", "CCK") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P, j);
+	}
+	else if ( STR_EQUAL_2G("2G", "B", "-", "CCK") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N, j);
+	}
+	else if ( STR_EQUAL_2G("2G", "A", "+", "ALL") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P, j);
+	}
+	else if ( STR_EQUAL_2G("2G", "A", "-", "ALL") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N, j);
+	}
+	else if ( STR_EQUAL_2G("2G", "B", "+", "ALL") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P, j);
+	}
+	else if ( STR_EQUAL_2G("2G", "B", "-", "ALL") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N, j);
+	}
+	else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "0") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[0], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "0") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[0], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "0") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[0], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "0") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[0], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "1") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[1], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "1") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[1], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "1") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[1], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "1") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[1], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "2") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[2], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "2") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[2], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "2") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[2], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "2") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[2], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "3") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[3], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "3") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[3], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "3") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[3], j);
+	}
+	else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "3") )
+	{
+		STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[3], j);
+	}
+	else
+	{
+ 		DBG_871X("===>initDeltaSwingIndexTables(): The input is invalid!!\n");
+	}
+}
+
+int
+PHY_ConfigRFWithTxPwrTrackParaFile(
+	IN	PADAPTER		Adapter,
+	IN	char*	 		pFileName
+)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T			pDM_Odm = &pHalData->odmpriv;
+	PODM_RF_CAL_T  		pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
+	int	rlen = 0, rtStatus = _FAIL;
+	char	*szLine, *ptmp;
+	u32	i = 0, j = 0;
+	char	c = 0;
+
+	if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE))
+		return rtStatus;
+
+	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+	if ((pHalData->rf_tx_pwr_track_len == 0) && (pHalData->rf_tx_pwr_track == NULL))
+	{
+		rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
+	
+		if (rtw_is_file_readable(file__path) == _TRUE)
+		{
+			rlen = rtw_retrieve_from_file(file__path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+			if (rlen > 0)
+			{
+				rtStatus = _SUCCESS;
+				pHalData->rf_tx_pwr_track = rtw_zvmalloc(rlen);
+				if(pHalData->rf_tx_pwr_track) {
+					_rtw_memcpy(pHalData->rf_tx_pwr_track, pHalData->para_file_buf, rlen);
+					pHalData->rf_tx_pwr_track_len = rlen;
+				}
+				else {
+					DBG_871X("%s rf_tx_pwr_track alloc fail !\n",__FUNCTION__);
+				}
+			}
+		}
+	}
+	else
+	{
+		if ((pHalData->rf_tx_pwr_track_len != 0) && (pHalData->rf_tx_pwr_track != NULL)) {
+			_rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
+			rtStatus = _SUCCESS;
+		}
+		else {
+			DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
+		}
+	}
+
+	if(rtStatus == _SUCCESS)
+	{
+		//DBG_871X("%s(): read %s successfully\n", __FUNCTION__, pFileName);
+
+		ptmp = pHalData->para_file_buf;
+		for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
+		{
+			if ( ! IsCommentString(szLine) )
+			{
+				char	band[5]="", path[5]="", sign[5]  = "";
+				char	chnl[5]="", rate[10]="";
+				char	data[300]=""; // 100 is too small
+
+				if (strlen(szLine) < 10 || szLine[0] != '[')
+					continue;
+
+				strncpy(band, szLine+1, 2); 
+				strncpy(path, szLine+5, 1); 
+				strncpy(sign, szLine+8, 1);
+
+				i = 10; // szLine+10
+				if ( ! ParseQualifiedString(szLine, &i, rate, '[', ']') ) {
+					//DBG_871X("Fail to parse rate!\n");
+				}
+				if ( ! ParseQualifiedString(szLine, &i, chnl, '[', ']') ) {
+					//DBG_871X("Fail to parse channel group!\n");
+				}
+				while ( szLine[i] != '{' && i < strlen(szLine))
+					i++;
+				if ( ! ParseQualifiedString(szLine, &i, data, '{', '}') ) {
+					//DBG_871X("Fail to parse data!\n");
+				}
+
+				initDeltaSwingIndexTables(Adapter, band, path, sign, chnl, rate, data);
+			}
+		}
+	}
+	else
+	{
+		DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
+	}
+#if 0
+	for (i = 0; i < DELTA_SWINGIDX_SIZE; ++i)
+	{
+		DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P[i]);
+		DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N[i]);
+		DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P[i]);
+		DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N[i]);
+		DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P[i]);
+		DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N[i]);
+		DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P[i]);
+		DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N[i]);
+
+		for (j = 0; j < 3; ++j)
+		{
+		    DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[j][i]);
+		    DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[j][i]);
+		    DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[j][i]);
+		    DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[j][i]);
+		}
+	}
+#endif
+	return rtStatus;
+}
+
+int
+phy_ParsePowerLimitTableFile(
+  PADAPTER		Adapter,
+  char*			buffer
+)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T	pDM_Odm = &(pHalData->odmpriv);
+	u32	i = 0, forCnt = 0;
+	u8	loadingStage = 0, limitValue = 0, fraction = 0;
+	char	*szLine, *ptmp;
+	int	rtStatus = _SUCCESS;
+	char band[10], bandwidth[10], rateSection[10],
+		regulation[TXPWR_LMT_MAX_REGULATION_NUM][10], rfPath[10],colNumBuf[10];
+	u8 	colNum = 0;
+
+	DBG_871X("===>phy_ParsePowerLimitTableFile()\n" );
+
+	if ( Adapter->registrypriv.RegDecryptCustomFile == 1 )
+		phy_DecryptBBPgParaFile( Adapter, buffer);
+
+	ptmp = buffer;
+	for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp))
+	{
+		if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
+			continue;
+
+		// skip comment 
+		if ( IsCommentString( szLine ) ) {
+			continue;
+		}
+
+		if( loadingStage == 0 ) {
+			for ( forCnt = 0; forCnt < TXPWR_LMT_MAX_REGULATION_NUM; ++forCnt )
+				_rtw_memset( ( PVOID ) regulation[forCnt], 0, 10 );
+			_rtw_memset( ( PVOID ) band, 0, 10 );
+			_rtw_memset( ( PVOID ) bandwidth, 0, 10 );
+			_rtw_memset( ( PVOID ) rateSection, 0, 10 );
+			_rtw_memset( ( PVOID ) rfPath, 0, 10 );
+			_rtw_memset( ( PVOID ) colNumBuf, 0, 10 );
+
+			if ( szLine[0] != '#' || szLine[1] != '#' )
+				continue;
+
+			// skip the space
+			i = 2;
+			while ( szLine[i] == ' ' || szLine[i] == '\t' )
+				++i;
+
+			szLine[--i] = ' '; // return the space in front of the regulation info
+
+			// Parse the label of the table
+			if ( ! ParseQualifiedString( szLine, &i, band, ' ', ',' ) ) {
+				DBG_871X( "Fail to parse band!\n");
+				return _FAIL;
+			}
+			if ( ! ParseQualifiedString( szLine, &i, bandwidth, ' ', ',' ) ) {
+				DBG_871X("Fail to parse bandwidth!\n");
+				return _FAIL;
+			}
+			if ( ! ParseQualifiedString( szLine, &i, rfPath, ' ', ',' ) ) {
+				DBG_871X("Fail to parse rf path!\n");
+				return _FAIL;
+			}
+			if ( ! ParseQualifiedString( szLine, &i, rateSection, ' ', ',' ) ) {
+				DBG_871X("Fail to parse rate!\n");
+				return _FAIL;
+			}
+
+			loadingStage = 1;
+		}
+		else if ( loadingStage == 1 )
+		{
+			if ( szLine[0] != '#' || szLine[1] != '#' )
+				continue;
+
+			// skip the space
+			i = 2;
+			while ( szLine[i] == ' ' || szLine[i] == '\t' )
+				++i;
+
+			if ( !eqNByte( (u8 *)(szLine + i), (u8 *)("START"), 5 ) ) {
+				DBG_871X("Lost \"##   START\" label\n");
+				return _FAIL;
+			}
+
+			loadingStage = 2;
+		}
+		else if ( loadingStage == 2 )
+		{
+			if ( szLine[0] != '#' || szLine[1] != '#' )
+				continue;
+
+			// skip the space
+			i = 2;
+			while ( szLine[i] == ' ' || szLine[i] == '\t' )
+				++i;
+
+			if ( ! ParseQualifiedString( szLine, &i, colNumBuf, '#', '#' ) ) {
+				DBG_871X("Fail to parse column number!\n");
+				return _FAIL;
+			}
+
+			if ( !GetU1ByteIntegerFromStringInDecimal( colNumBuf, &colNum ) )
+				return _FAIL;
+
+			if ( colNum > TXPWR_LMT_MAX_REGULATION_NUM ) {
+				DBG_871X("unvalid col number %d (greater than max %d)\n", 
+				          colNum, TXPWR_LMT_MAX_REGULATION_NUM );
+				return _FAIL;
+			}
+
+			for ( forCnt = 0; forCnt < colNum; ++forCnt )
+			{
+				u8	regulation_name_cnt = 0;
+
+				// skip the space
+				while ( szLine[i] == ' ' || szLine[i] == '\t' )
+					++i;
+
+				while ( szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0' )
+					regulation[forCnt][regulation_name_cnt++] = szLine[i++];
+				//DBG_871X("regulation %s!\n", regulation[forCnt]);
+
+				if ( regulation_name_cnt == 0 ) {
+					DBG_871X("unvalid number of regulation!\n");
+					return _FAIL;
+				}
+			}
+
+			loadingStage = 3;
+		}
+		else if ( loadingStage == 3 )
+		{
+			char	channel[10] = {0}, powerLimit[10] = {0};
+			u8	cnt = 0;
+			
+			// the table ends
+			if ( szLine[0] == '#' && szLine[1] == '#' ) {
+				i = 2;
+				while ( szLine[i] == ' ' || szLine[i] == '\t' )
+					++i;
+
+				if ( eqNByte( (u8 *)(szLine + i), (u8 *)("END"), 3 ) ) {
+					loadingStage = 0;
+					continue;
+				}
+				else {
+					DBG_871X("Wrong format\n");
+					DBG_871X("<===== phy_ParsePowerLimitTableFile()\n");
+					return _FAIL;
+				}
+			}
+
+			if ( ( szLine[0] != 'c' && szLine[0] != 'C' ) || 
+				 ( szLine[1] != 'h' && szLine[1] != 'H' ) ) {
+				DBG_871X("Meet wrong channel => power limt pair '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]);
+				continue;
+			}
+			i = 2;// move to the  location behind 'h'
+
+			// load the channel number
+			cnt = 0;
+			while ( szLine[i] >= '0' && szLine[i] <= '9' ) {
+				channel[cnt] = szLine[i];
+				++cnt;
+				++i;
+			}
+			//DBG_871X("chnl %s!\n", channel);
+			
+			for ( forCnt = 0; forCnt < colNum; ++forCnt )
+			{
+				// skip the space between channel number and the power limit value
+				while ( szLine[i] == ' ' || szLine[i] == '\t' )
+					++i;
+
+				// load the power limit value
+				cnt = 0;
+				fraction = 0;
+				_rtw_memset( ( PVOID ) powerLimit, 0, 10 );
+				while ( ( szLine[i] >= '0' && szLine[i] <= '9' ) || szLine[i] == '.' )
+				{
+					if ( szLine[i] == '.' ){
+						if ( ( szLine[i+1] >= '0' && szLine[i+1] <= '9' ) ) {
+							fraction = szLine[i+1];
+							i += 2;
+						}
+						else {
+							DBG_871X("Wrong fraction in TXPWR_LMT.txt\n");
+							return _FAIL;
+						}
+
+						break;
+					}
+
+					powerLimit[cnt] = szLine[i];
+					++cnt;
+					++i;
+				}
+
+				if ( powerLimit[0] == '\0' ) {
+					powerLimit[0] = '6';
+					powerLimit[1] = '3';
+					i += 2;
+				}
+				else {
+					if ( !GetU1ByteIntegerFromStringInDecimal( powerLimit, &limitValue ) )
+						return _FAIL;
+
+					limitValue *= 2;
+					cnt = 0;
+					if ( fraction == '5' )
+						++limitValue;
+
+					// the value is greater or equal to 100
+					if ( limitValue >= 100 ) {
+						powerLimit[cnt++] = limitValue/100 + '0';
+						limitValue %= 100;
+
+						if ( limitValue >= 10 ) {
+							powerLimit[cnt++] = limitValue/10 + '0';
+							limitValue %= 10;
+						}
+						else {
+							powerLimit[cnt++] = '0';
+						}
+
+						powerLimit[cnt++] = limitValue + '0';
+					}
+					// the value is greater or equal to 10
+					else if ( limitValue >= 10 ) {
+						powerLimit[cnt++] = limitValue/10 + '0';
+						limitValue %= 10;
+						powerLimit[cnt++] = limitValue + '0';
+					}
+					// the value is less than 10 
+					else
+						powerLimit[cnt++] = limitValue + '0';
+
+					powerLimit[cnt] = '\0';
+				}
+
+				//DBG_871X("ch%s => %s\n", channel, powerLimit);
+
+				// store the power limit value
+				PHY_SetTxPowerLimit(pDM_Odm, (u8 *)regulation[forCnt], (u8 *)band,
+					(u8 *)bandwidth, (u8 *)rateSection, (u8 *)rfPath, (u8 *)channel, (u8 *)powerLimit );
+
+			}
+		}
+		else 
+		{
+			DBG_871X("Abnormal loading stage in phy_ParsePowerLimitTableFile()!\n");
+			rtStatus = _FAIL;
+			break;
+		}
+	}
+
+	DBG_871X("<===phy_ParsePowerLimitTableFile()\n");
+	return rtStatus;
+}
+
+int
+PHY_ConfigRFWithPowerLimitTableParaFile(
+	IN	PADAPTER	Adapter,
+	IN	const char	*pFileName
+)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+	int	rlen = 0, rtStatus = _FAIL;
+
+	if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_LMT_PARA_FILE))
+		return rtStatus;
+
+	_rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+	if (pHalData->rf_tx_pwr_lmt == NULL) {
+		rtw_merge_string(file__path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName);
+	
+		if (rtw_is_file_readable(file__path) == _TRUE)
+		{
+			rlen = rtw_retrieve_from_file(file__path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+			if (rlen > 0)
+			{
+				rtStatus = _SUCCESS;
+				pHalData->rf_tx_pwr_lmt = rtw_zvmalloc(rlen);
+				if(pHalData->rf_tx_pwr_lmt) {
+					_rtw_memcpy(pHalData->rf_tx_pwr_lmt, pHalData->para_file_buf, rlen);
+					pHalData->rf_tx_pwr_lmt_len = rlen;
+				}
+				else {
+					DBG_871X("%s rf_tx_pwr_lmt alloc fail !\n",__FUNCTION__);
+				}
+			}
+		}
+	} else {
+		if ((pHalData->rf_tx_pwr_lmt_len != 0) && (pHalData->rf_tx_pwr_lmt != NULL)) {
+			_rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
+			rtStatus = _SUCCESS;
+		}
+		else {
+			DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__);
+		}
+	}
+
+	if(rtStatus == _SUCCESS)
+	{
+		//DBG_871X("%s(): read %s ok\n", __FUNCTION__, pFileName);
+		rtStatus = phy_ParsePowerLimitTableFile( Adapter, pHalData->para_file_buf );
+	}
+	else
+	{
+		DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName);
+	}
+
+	return rtStatus;
+}
+
+void phy_free_filebuf_mask(_adapter *padapter, u8 mask)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+	if (pHalData->mac_reg && (mask & LOAD_MAC_PARA_FILE)) {
+		rtw_vmfree(pHalData->mac_reg, pHalData->mac_reg_len);
+		pHalData->mac_reg = NULL;
+	}
+	if (mask & LOAD_BB_PARA_FILE) {
+		if (pHalData->bb_phy_reg) {
+			rtw_vmfree(pHalData->bb_phy_reg, pHalData->bb_phy_reg_len);
+			pHalData->bb_phy_reg = NULL;
+		}
+		if (pHalData->bb_agc_tab) {
+			rtw_vmfree(pHalData->bb_agc_tab, pHalData->bb_agc_tab_len);
+			pHalData->bb_agc_tab = NULL;
+		}
+	}
+	if (pHalData->bb_phy_reg_pg && (mask & LOAD_BB_PG_PARA_FILE)) {
+		rtw_vmfree(pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
+		pHalData->bb_phy_reg_pg = NULL;
+	}
+	if (pHalData->bb_phy_reg_mp && (mask & LOAD_BB_MP_PARA_FILE)) {
+		rtw_vmfree(pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
+		pHalData->bb_phy_reg_mp = NULL;
+	}
+	if (mask & LOAD_RF_PARA_FILE) {
+		if (pHalData->rf_radio_a) {
+			rtw_vmfree(pHalData->rf_radio_a, pHalData->rf_radio_a_len);
+			pHalData->rf_radio_a = NULL;
+		}
+		if (pHalData->rf_radio_b) {
+			rtw_vmfree(pHalData->rf_radio_b, pHalData->rf_radio_b_len);
+			pHalData->rf_radio_b = NULL;
+		}
+	}
+	if (pHalData->rf_tx_pwr_track && (mask & LOAD_RF_TXPWR_TRACK_PARA_FILE)) {
+		rtw_vmfree(pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
+		pHalData->rf_tx_pwr_track = NULL;
+	}
+	if (pHalData->rf_tx_pwr_lmt && (mask & LOAD_RF_TXPWR_LMT_PARA_FILE)) {
+		rtw_vmfree(pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
+		pHalData->rf_tx_pwr_lmt = NULL;
+	}
+}
+
+inline void phy_free_filebuf(_adapter *padapter)
+{
+	phy_free_filebuf_mask(padapter, 0xFF);
+}
+
+#endif
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_dm.c b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_dm.c
new file mode 100644
index 000000000..5b5d3de9c
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_dm.c
@@ -0,0 +1,195 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2014 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 <drv_types.h>
+#include <hal_data.h>
+
+// A mapping from HalData to ODM.
+ODM_BOARD_TYPE_E boardType(u8 InterfaceSel)
+{
+    ODM_BOARD_TYPE_E        board	= ODM_BOARD_DEFAULT;
+
+#ifdef CONFIG_PCI_HCI
+	INTERFACE_SELECT_PCIE   pcie 	= (INTERFACE_SELECT_PCIE)InterfaceSel;
+	switch (pcie) 
+	{
+        case INTF_SEL0_SOLO_MINICARD:       
+            board |= ODM_BOARD_MINICARD;
+            break;
+        case INTF_SEL1_BT_COMBO_MINICARD:   
+            board |= ODM_BOARD_BT;
+			board |= ODM_BOARD_MINICARD;
+            break;
+        default:
+            board = ODM_BOARD_DEFAULT;
+            break;
+	}                                
+
+#elif defined(CONFIG_USB_HCI)
+	INTERFACE_SELECT_USB    usb 	= (INTERFACE_SELECT_USB)InterfaceSel;
+	switch (usb) 
+	{
+	    case INTF_SEL1_USB_High_Power:      
+	        board |= ODM_BOARD_EXT_LNA;
+	        board |= ODM_BOARD_EXT_PA;			
+	        break;
+	    case INTF_SEL2_MINICARD:            
+	        board |= ODM_BOARD_MINICARD;
+	        break;
+	    case INTF_SEL4_USB_Combo:           
+	        board |= ODM_BOARD_BT;
+	        break;
+	    case INTF_SEL5_USB_Combo_MF:        
+	        board |= ODM_BOARD_BT;
+	        break;
+	    case INTF_SEL0_USB: 			
+	    case INTF_SEL3_USB_Solo:            			
+	    default:
+	        board = ODM_BOARD_DEFAULT;
+	        break;
+	}
+	
+#endif	
+	//DBG_871X("===> boardType(): (pHalData->InterfaceSel, pDM_Odm->BoardType) = (%d, %d)\n", InterfaceSel, board);
+
+	return board;
+}
+
+void Init_ODM_ComInfo(_adapter *adapter)
+{
+	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(adapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
+	struct mlme_priv	*pmlmepriv = &adapter->mlmepriv;
+	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+	int i;
+
+	_rtw_memset(pDM_Odm,0,sizeof(*pDM_Odm));
+
+	pDM_Odm->Adapter = adapter;
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PLATFORM, ODM_CE);
+
+	rtw_odm_init_ic_type(adapter);
+
+	if (rtw_get_intf_type(adapter) == RTW_GSPI)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_INTERFACE, ODM_ITRF_SDIO);
+	else
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_INTERFACE, rtw_get_intf_type(adapter));
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(pHalData->VersionID));
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PATCH_ID, pHalData->CustomerID);
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, adapter->registrypriv.wifi_spec);
+
+
+	if (pHalData->rf_type == RF_1T1R)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R);
+	else if (pHalData->rf_type == RF_1T2R)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R);
+	else if (pHalData->rf_type == RF_2T2R)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R);
+	else if (pHalData->rf_type == RF_2T2R_GREEN)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R_GREEN);
+	else if (pHalData->rf_type == RF_2T3R)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T3R);
+	else if (pHalData->rf_type == RF_2T4R)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T4R);
+	else if (pHalData->rf_type == RF_3T3R)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_3T3R);
+	else if (pHalData->rf_type == RF_3T4R)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_3T4R);
+	else if (pHalData->rf_type == RF_4T4R)
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_4T4R);
+	else
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_XTXR);
+	
+
+{
+	//1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE =======
+	u8 odm_board_type = ODM_BOARD_DEFAULT;
+
+	if (pHalData->ExternalLNA_2G != 0) {
+		odm_board_type |= ODM_BOARD_EXT_LNA;
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_EXT_LNA, 1);
+	}
+	if (pHalData->ExternalLNA_5G != 0) {
+		odm_board_type |= ODM_BOARD_EXT_LNA_5G;
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_5G_EXT_LNA, 1);
+	}
+	if (pHalData->ExternalPA_2G != 0) {
+		odm_board_type |= ODM_BOARD_EXT_PA;
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_EXT_PA, 1);
+	}
+	if (pHalData->ExternalPA_5G != 0) {
+		odm_board_type |= ODM_BOARD_EXT_PA_5G;
+		ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_5G_EXT_PA, 1);
+	}
+	if (pHalData->EEPROMBluetoothCoexist)
+		odm_board_type |= ODM_BOARD_BT;	
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_BOARD_TYPE, odm_board_type);
+	//1 ============== End of BoardType ==============
+}
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G);
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G);
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_GPA, pHalData->TypeGPA);
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_APA, pHalData->TypeAPA);
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_GLNA, pHalData->TypeGLNA);
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_ALNA, pHalData->TypeALNA);
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RFE_TYPE, pHalData->RFEType);
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_EXT_TRSW, 0);
+
+	/* Pointer reference */
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_TX_UNI, &(dvobj->traffic_stat.tx_bytes));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_RX_UNI, &(dvobj->traffic_stat.rx_bytes));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_WM_MODE, &(pmlmeext->cur_wireless_mode));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BAND, &(pHalData->CurrentBandType));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_FORCED_RATE, &(pHalData->ForcedDataRate));
+
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_CHNL_OFFSET, &(pHalData->nCur40MhzPrimeSC));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_MODE, &(adapter->securitypriv.dot11PrivacyAlgrthm));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BW, &(pHalData->CurrentChannelBW));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_CHNL, &( pHalData->CurrentChannel));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_NET_CLOSED, &(adapter->net_closed));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_FORCED_IGI_LB, &(pHalData->u1ForcedIgiLb));
+
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SCAN, &(pmlmepriv->bScanInProcess));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_POWER_SAVING, &(pwrctl->bpower_saving));
+	/*Add by Yuchen for phydm beamforming*/
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_TX_TP, &(dvobj->traffic_stat.cur_tx_tp));
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_RX_TP, &(dvobj->traffic_stat.cur_rx_tp));
+#ifdef CONFIG_USB_HCI
+	ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_HUBUSBMODE, &(dvobj->usb_speed));
+#endif
+	for(i=0; i<ODM_ASSOCIATE_ENTRY_NUM; i++)
+		ODM_CmnInfoPtrArrayHook(pDM_Odm, ODM_CMNINFO_STA_STATUS, i, NULL);
+
+	/* TODO */
+	//ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BT_OPERATION, _FALSE);
+	//ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BT_DISABLE_EDCA, _FALSE);
+}
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_dm.h b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_dm.h
new file mode 100644
index 000000000..78236ccf2
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_dm.h
@@ -0,0 +1,26 @@
+/******************************************************************************
+ *
+ * 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 __HAL_DM_H__
+#define __HAL_DM_H__
+
+void Init_ODM_ComInfo(_adapter *adapter);
+
+#endif /* __HAL_DM_H__ */
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_hci/hal_sdio.c b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_hci/hal_sdio.c
new file mode 100644
index 000000000..1ee0a9ddd
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_hci/hal_sdio.c
@@ -0,0 +1,112 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#define _HAL_SDIO_C_
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+u8 rtw_hal_sdio_max_txoqt_free_space(_adapter *padapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+	if(pHalData->SdioTxOQTMaxFreeSpace < 8 )
+		pHalData->SdioTxOQTMaxFreeSpace = 8;
+
+	return pHalData->SdioTxOQTMaxFreeSpace;	
+}
+
+u8 rtw_hal_sdio_query_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+	if ((pHalData->SdioTxFIFOFreePage[PageIdx]+pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]) >= (RequiredPageNum))
+		return _TRUE;
+	else
+		return _FALSE;
+}
+
+void rtw_hal_sdio_update_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u8	DedicatedPgNum = 0;
+	u8	RequiredPublicFreePgNum = 0;
+	//_irqL irql;
+
+	//_enter_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql);
+
+	DedicatedPgNum = pHalData->SdioTxFIFOFreePage[PageIdx];
+	if (RequiredPageNum <= DedicatedPgNum) {
+		pHalData->SdioTxFIFOFreePage[PageIdx] -= RequiredPageNum;
+	} else {
+		pHalData->SdioTxFIFOFreePage[PageIdx] = 0;
+		RequiredPublicFreePgNum = RequiredPageNum - DedicatedPgNum;
+		pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= RequiredPublicFreePgNum;
+	}
+
+	//_exit_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql);
+}
+
+void rtw_hal_set_sdio_tx_max_length(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u32	page_size;
+	u32	lenHQ, lenNQ, lenLQ;
+
+	rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE,&page_size);
+
+	lenHQ = ((numHQ + numPubQ) >> 1) * page_size;
+	lenNQ = ((numNQ + numPubQ) >> 1) * page_size;
+	lenLQ = ((numLQ + numPubQ) >> 1) * page_size;
+
+	pHalData->sdio_tx_max_len[HI_QUEUE_IDX] = (lenHQ > MAX_XMITBUF_SZ)? MAX_XMITBUF_SZ:lenHQ;
+	pHalData->sdio_tx_max_len[MID_QUEUE_IDX] = (lenNQ > MAX_XMITBUF_SZ)? MAX_XMITBUF_SZ:lenNQ;
+	pHalData->sdio_tx_max_len[LOW_QUEUE_IDX] = (lenLQ > MAX_XMITBUF_SZ)? MAX_XMITBUF_SZ:lenLQ;
+}
+
+u32 rtw_hal_get_sdio_tx_max_length(PADAPTER padapter, u8 queue_idx)
+{
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u32	deviceId, max_len;
+	
+
+	deviceId = ffaddr2deviceId(pdvobjpriv, queue_idx);
+	switch (deviceId) {
+		case WLAN_TX_HIQ_DEVICE_ID:
+			max_len = pHalData->sdio_tx_max_len[HI_QUEUE_IDX];
+			break;
+
+		case WLAN_TX_MIQ_DEVICE_ID:
+			max_len = pHalData->sdio_tx_max_len[MID_QUEUE_IDX];
+			break;
+
+		case WLAN_TX_LOQ_DEVICE_ID:
+			max_len = pHalData->sdio_tx_max_len[LOW_QUEUE_IDX];
+			break;
+
+		default:
+			max_len = pHalData->sdio_tx_max_len[MID_QUEUE_IDX];
+			break;
+	}
+
+	return max_len;
+}
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_intf.c b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_intf.c
new file mode 100644
index 000000000..b9dad0dd5
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_intf.c
@@ -0,0 +1,1128 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *
+ ******************************************************************************/
+
+#define _HAL_INTF_C_
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+const u32 _chip_type_to_odm_ic_type[] = {
+	0,
+	ODM_RTL8188E,
+	ODM_RTL8192E,
+	ODM_RTL8812,
+	ODM_RTL8821,
+	ODM_RTL8723B,
+	ODM_RTL8814A,
+	ODM_RTL8703B,
+	ODM_RTL8188F,
+	0,
+};
+
+void rtw_hal_chip_configure(_adapter *padapter)
+{
+	padapter->HalFunc.intf_chip_configure(padapter);
+}
+
+void rtw_hal_read_chip_info(_adapter *padapter)
+{
+	u8 hci_type = rtw_get_intf_type(padapter);
+	u32 start = rtw_get_current_time();
+
+	/*  before access eFuse, make sure card enable has been called */
+	if ((hci_type == RTW_SDIO || hci_type == RTW_GSPI)
+		&& !rtw_is_hw_init_completed(padapter))
+		rtw_hal_power_on(padapter);
+
+	padapter->HalFunc.read_adapter_info(padapter);
+
+	if ((hci_type == RTW_SDIO || hci_type == RTW_GSPI)
+		&& !rtw_is_hw_init_completed(padapter))
+		rtw_hal_power_off(padapter);
+
+	DBG_871X("%s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
+}
+
+void rtw_hal_read_chip_version(_adapter *padapter)
+{
+	padapter->HalFunc.read_chip_version(padapter);
+	rtw_odm_init_ic_type(padapter);
+}
+
+void rtw_hal_def_value_init(_adapter *padapter)
+{
+	if (is_primary_adapter(padapter)) {
+		padapter->HalFunc.init_default_value(padapter);
+
+		rtw_init_hal_com_default_value(padapter);
+
+		{
+			struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+			struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
+
+			/* hal_spec is ready here */
+			dvobj->macid_ctl.num = rtw_min(hal_spec->macid_num, MACID_NUM_SW_LIMIT);
+
+			dvobj->cam_ctl.sec_cap = hal_spec->sec_cap;
+			dvobj->cam_ctl.num = rtw_min(hal_spec->sec_cam_ent_num, SEC_CAM_ENT_NUM_SW_LIMIT);
+		}
+	}
+}
+
+u8 rtw_hal_data_init(_adapter *padapter)
+{
+	if (is_primary_adapter(padapter)) {
+		padapter->hal_data_sz = sizeof(HAL_DATA_TYPE);
+		padapter->HalData = rtw_zvmalloc(padapter->hal_data_sz);
+		if(padapter->HalData == NULL){
+			DBG_8192C("cant not alloc memory for HAL DATA \n");
+			return _FAIL;
+		}
+	}
+	return _SUCCESS;
+}
+
+void rtw_hal_data_deinit(_adapter *padapter)
+{	
+	if (is_primary_adapter(padapter)) {
+		if (padapter->HalData) 
+		{
+			#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+			phy_free_filebuf(padapter);				
+			#endif
+			rtw_vmfree(padapter->HalData, padapter->hal_data_sz);
+			padapter->HalData = NULL;
+			padapter->hal_data_sz = 0;
+		}	
+	}
+}
+
+void	rtw_hal_free_data(_adapter *padapter)
+{
+	//free HAL Data 	
+	rtw_hal_data_deinit(padapter);	
+}
+void rtw_hal_dm_init(_adapter *padapter)
+{
+	if (is_primary_adapter(padapter)) {
+		PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+		
+		padapter->HalFunc.dm_init(padapter);
+
+		_rtw_spinlock_init(&pHalData->IQKSpinLock);
+
+		phy_load_tx_power_ext_info(padapter, 1, 1);
+	}
+}
+void rtw_hal_dm_deinit(_adapter *padapter)
+{
+	if (is_primary_adapter(padapter)) {
+		PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);		
+
+		padapter->HalFunc.dm_deinit(padapter);
+
+		_rtw_spinlock_free(&pHalData->IQKSpinLock);
+	}
+}
+void	rtw_hal_sw_led_init(_adapter *padapter)
+{
+	if(padapter->HalFunc.InitSwLeds)
+		padapter->HalFunc.InitSwLeds(padapter);
+}
+
+void rtw_hal_sw_led_deinit(_adapter *padapter)
+{
+	if(padapter->HalFunc.DeInitSwLeds)
+		padapter->HalFunc.DeInitSwLeds(padapter);
+}
+
+u32 rtw_hal_power_on(_adapter *padapter)
+{	
+	return padapter->HalFunc.hal_power_on(padapter);
+}
+void rtw_hal_power_off(_adapter *padapter)
+{
+	struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
+
+	_rtw_memset(macid_ctl->h2c_msr, 0, MACID_NUM_SW_LIMIT);
+
+	padapter->HalFunc.hal_power_off(padapter);
+}
+
+
+void rtw_hal_init_opmode(_adapter *padapter) 
+{
+	NDIS_802_11_NETWORK_INFRASTRUCTURE networkType = Ndis802_11InfrastructureMax;
+	struct  mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+	sint fw_state;
+
+	fw_state = get_fwstate(pmlmepriv);
+
+	if (fw_state & WIFI_ADHOC_STATE) 
+		networkType = Ndis802_11IBSS;
+	else if (fw_state & WIFI_STATION_STATE)
+		networkType = Ndis802_11Infrastructure;
+	else if (fw_state & WIFI_AP_STATE)
+		networkType = Ndis802_11APMode;
+	else
+		return;
+
+	rtw_setopmode_cmd(padapter, networkType, _FALSE); 
+}
+
+uint	 rtw_hal_init(_adapter *padapter) 
+{
+	uint	status = _SUCCESS;
+	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	int i;
+
+	status = padapter->HalFunc.hal_init(padapter);
+	
+	if (status == _SUCCESS) {
+		pHalData->hw_init_completed = _TRUE;
+			
+		if (padapter->registrypriv.notch_filter == 1)
+			rtw_hal_notch_filter(padapter, 1);
+
+		for (i = 0; i<dvobj->iface_nums; i++)
+			rtw_sec_restore_wep_key(dvobj->padapters[i]);
+
+		rtw_led_control(padapter, LED_CTL_POWER_ON);
+
+		init_hw_mlme_ext(padapter);
+
+                rtw_hal_init_opmode(padapter);
+		
+#ifdef CONFIG_RF_GAIN_OFFSET
+		rtw_bb_rf_gain_offset(padapter);
+#endif //CONFIG_RF_GAIN_OFFSET
+
+	} else {
+		pHalData->hw_init_completed = _FALSE;
+		DBG_871X("rtw_hal_init: hal__init fail\n");
+	}
+
+	RT_TRACE(_module_hal_init_c_,_drv_err_,("-rtl871x_hal_init:status=0x%x\n",status));
+
+	return status;
+
+}	
+
+uint rtw_hal_deinit(_adapter *padapter)
+{
+	uint	status = _SUCCESS;
+	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	int i;
+_func_enter_;
+
+	status = padapter->HalFunc.hal_deinit(padapter);
+
+	if(status == _SUCCESS){
+		rtw_led_control(padapter, LED_CTL_POWER_OFF);
+		pHalData->hw_init_completed = _FALSE;
+	}
+	else
+	{
+		DBG_871X("\n rtw_hal_deinit: hal_init fail\n");
+	}
+
+_func_exit_;
+	
+	return status;
+}
+
+void rtw_hal_set_hwreg(_adapter *padapter, u8 variable, u8 *val)
+{
+	padapter->HalFunc.SetHwRegHandler(padapter, variable, val);
+}
+
+void rtw_hal_get_hwreg(_adapter *padapter, u8 variable, u8 *val)
+{
+	padapter->HalFunc.GetHwRegHandler(padapter, variable, val);
+}
+
+#ifdef CONFIG_C2H_PACKET_EN
+void rtw_hal_set_hwreg_with_buf(_adapter *padapter, u8 variable, u8 *pbuf, int len)
+{
+	if (padapter->HalFunc.SetHwRegHandlerWithBuf)
+		padapter->HalFunc.SetHwRegHandlerWithBuf(padapter, variable, pbuf, len);
+}
+#endif
+
+u8 rtw_hal_set_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue)
+{	
+	return padapter->HalFunc.SetHalDefVarHandler(padapter,eVariable,pValue);
+}
+u8 rtw_hal_get_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue)
+{	
+	return padapter->HalFunc.GetHalDefVarHandler(padapter,eVariable,pValue);		
+}	
+
+void rtw_hal_set_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,BOOLEAN bSet)
+{
+	padapter->HalFunc.SetHalODMVarHandler(padapter,eVariable,pValue1,bSet);
+}
+void	rtw_hal_get_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,PVOID pValue2)
+{
+	padapter->HalFunc.GetHalODMVarHandler(padapter,eVariable,pValue1,pValue2);
+}
+
+/* FOR SDIO & PCIE */
+void rtw_hal_enable_interrupt(_adapter *padapter)
+{
+#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
+	padapter->HalFunc.enable_interrupt(padapter);	
+#endif //#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
+}
+
+/* FOR SDIO & PCIE */
+void rtw_hal_disable_interrupt(_adapter *padapter)
+{
+#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
+	padapter->HalFunc.disable_interrupt(padapter);
+#endif //#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
+}
+
+
+u8 rtw_hal_check_ips_status(_adapter *padapter)
+{
+	u8 val = _FALSE;
+	if (padapter->HalFunc.check_ips_status)
+		val = padapter->HalFunc.check_ips_status(padapter);
+	else 
+		DBG_871X("%s: HalFunc.check_ips_status is NULL!\n", __FUNCTION__);
+	
+	return val;
+}
+
+s32 rtw_hal_fw_dl(_adapter *padapter, u8 wowlan)
+{
+	return padapter->HalFunc.fw_dl(padapter, wowlan);
+}
+
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+void rtw_hal_clear_interrupt(_adapter *padapter)
+{  
+#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+	padapter->HalFunc.clear_interrupt(padapter);
+#endif
+}
+#endif
+
+#if defined(CONFIG_USB_HCI) || defined (CONFIG_PCI_HCI)
+u32	rtw_hal_inirp_init(_adapter *padapter)
+{
+	if (is_primary_adapter(padapter)) 		
+		return padapter->HalFunc.inirp_init(padapter);	
+	 return _SUCCESS;
+}
+u32	rtw_hal_inirp_deinit(_adapter *padapter)
+{
+
+	if (is_primary_adapter(padapter)) 	
+		return padapter->HalFunc.inirp_deinit(padapter);
+
+	return _SUCCESS;
+}
+#endif //#if defined(CONFIG_USB_HCI) || defined (CONFIG_PCI_HCI)
+
+#if defined(CONFIG_PCI_HCI)
+void	rtw_hal_irp_reset(_adapter *padapter)
+{
+	padapter->HalFunc.irp_reset(padapter);
+}
+#endif //#if defined(CONFIG_PCI_HCI)
+
+/* for USB Auto-suspend */
+u8	rtw_hal_intf_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id, u8* val)
+{	
+	if(padapter->HalFunc.interface_ps_func)	
+		return padapter->HalFunc.interface_ps_func(padapter,efunc_id,val);
+	return _FAIL;
+}
+
+s32	rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+	return padapter->HalFunc.hal_xmitframe_enqueue(padapter, pxmitframe);
+}
+
+s32	rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+	return padapter->HalFunc.hal_xmit(padapter, pxmitframe);
+}
+
+/*
+ * [IMPORTANT] This function would be run in interrupt context.
+ */
+s32	rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
+{
+	s32 ret = _FAIL;
+	u8	*pframe, subtype;
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	struct sta_info	*psta;
+	struct sta_priv		*pstapriv = &padapter->stapriv;
+	
+	update_mgntframe_attrib_addr(padapter, pmgntframe);
+	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+	subtype = GetFrameSubType(pframe); /* bit(7)~bit(2) */
+	
+	//pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+	//_rtw_memcpy(pmgntframe->attrib.ra, pwlanhdr->addr1, ETH_ALEN);
+
+#ifdef CONFIG_IEEE80211W
+	if (padapter->securitypriv.binstallBIPkey == _TRUE && (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC ||
+			subtype == WIFI_ACTION))
+	{
+		if (IS_MCAST(pmgntframe->attrib.ra) && pmgntframe->attrib.key_type != IEEE80211W_NO_KEY) {
+			pmgntframe->attrib.encrypt = _BIP_;
+			/* pmgntframe->attrib.bswenc = _TRUE; */
+		} else if (pmgntframe->attrib.key_type != IEEE80211W_NO_KEY) {
+			psta = rtw_get_stainfo(pstapriv, pmgntframe->attrib.ra);
+			if (psta && psta->bpairwise_key_installed == _TRUE) {
+				pmgntframe->attrib.encrypt = _AES_;
+				pmgntframe->attrib.bswenc = _TRUE;
+			} else {
+				DBG_871X("%s, %d, bpairwise_key_installed is FALSE\n", __func__, __LINE__);
+				goto no_mgmt_coalesce;
+			}
+		}
+		DBG_871X("encrypt=%d, bswenc=%d\n", pmgntframe->attrib.encrypt, pmgntframe->attrib.bswenc);
+		rtw_mgmt_xmitframe_coalesce(padapter, pmgntframe->pkt, pmgntframe);
+	}
+#endif //CONFIG_IEEE80211W
+no_mgmt_coalesce:
+	ret = padapter->HalFunc.mgnt_xmit(padapter, pmgntframe);
+	return ret;
+}
+
+s32	rtw_hal_init_xmit_priv(_adapter *padapter)
+{	
+	return padapter->HalFunc.init_xmit_priv(padapter);	
+}
+void	rtw_hal_free_xmit_priv(_adapter *padapter)
+{
+	padapter->HalFunc.free_xmit_priv(padapter);
+}
+
+s32	rtw_hal_init_recv_priv(_adapter *padapter)
+{	
+	return padapter->HalFunc.init_recv_priv(padapter);
+}
+void	rtw_hal_free_recv_priv(_adapter *padapter)
+{
+	padapter->HalFunc.free_recv_priv(padapter);
+}
+
+void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level)
+{
+	_adapter *padapter;
+	struct mlme_priv *pmlmepriv;
+
+	if(!psta)
+		return;
+
+	padapter = psta->padapter;
+
+	pmlmepriv = &(padapter->mlmepriv);
+	
+	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
+	{
+		add_RATid(padapter, psta, rssi_level);
+	}
+	else
+	{
+		padapter->HalFunc.UpdateRAMaskHandler(padapter, psta->mac_id, rssi_level);
+	}
+}
+
+void	rtw_hal_add_ra_tid(_adapter *padapter, u64 bitmap, u8 *arg, u8 rssi_level)
+{
+	padapter->HalFunc.Add_RateATid(padapter, bitmap, arg, rssi_level);
+}
+
+/*	Start specifical interface thread		*/
+void	rtw_hal_start_thread(_adapter *padapter)
+{
+#if defined(CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
+#ifndef CONFIG_SDIO_TX_TASKLET	
+	padapter->HalFunc.run_thread(padapter);	
+#endif
+#endif
+}
+/*	Start specifical interface thread		*/
+void	rtw_hal_stop_thread(_adapter *padapter)
+{
+#if defined(CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
+#ifndef CONFIG_SDIO_TX_TASKLET
+	
+	padapter->HalFunc.cancel_thread(padapter);
+	
+#endif
+#endif	
+}
+
+u32	rtw_hal_read_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask)
+{
+	u32 data = 0;
+	if(padapter->HalFunc.read_bbreg)
+		 data = padapter->HalFunc.read_bbreg(padapter, RegAddr, BitMask);
+	return data;
+}
+void	rtw_hal_write_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data)
+{
+	if(padapter->HalFunc.write_bbreg)
+		padapter->HalFunc.write_bbreg(padapter, RegAddr, BitMask, Data);
+}
+
+u32 rtw_hal_read_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask)
+{
+	u32 data = 0;
+
+	if (padapter->HalFunc.read_rfreg) {
+		data = padapter->HalFunc.read_rfreg(padapter, eRFPath, RegAddr, BitMask);
+
+		if (match_rf_read_sniff_ranges(eRFPath, RegAddr, BitMask)) {
+			DBG_871X("DBG_IO rtw_hal_read_rfreg(%u, 0x%04x, 0x%08x) read:0x%08x(0x%08x)\n"
+				, eRFPath, RegAddr, BitMask, (data << PHY_CalculateBitShift(BitMask)), data);
+		}
+	}
+
+	return data;
+}
+
+void rtw_hal_write_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
+{
+	if (padapter->HalFunc.write_rfreg) {
+
+		if (match_rf_write_sniff_ranges(eRFPath, RegAddr, BitMask)) {
+			DBG_871X("DBG_IO rtw_hal_write_rfreg(%u, 0x%04x, 0x%08x) write:0x%08x(0x%08x)\n"
+				, eRFPath, RegAddr, BitMask, (Data << PHY_CalculateBitShift(BitMask)), Data);
+		}
+
+		padapter->HalFunc.write_rfreg(padapter, eRFPath, RegAddr, BitMask, Data);
+
+#ifdef CONFIG_PCI_HCI
+		if (!IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(padapter)) /*For N-Series IC, suggest by Jenyu*/
+			rtw_udelay_os(2);
+#endif
+	}
+}
+
+#if defined(CONFIG_PCI_HCI)
+s32	rtw_hal_interrupt_handler(_adapter *padapter)
+{
+	s32 ret = _FAIL;
+	ret = padapter->HalFunc.interrupt_handler(padapter);
+	return ret;
+}
+#endif
+#if defined(CONFIG_USB_HCI) && defined(CONFIG_SUPPORT_USB_INT)
+void	rtw_hal_interrupt_handler(_adapter *padapter, u16 pkt_len, u8 *pbuf)
+{
+	padapter->HalFunc.interrupt_handler(padapter, pkt_len, pbuf);
+}
+#endif
+
+void	rtw_hal_set_bwmode(_adapter *padapter, CHANNEL_WIDTH Bandwidth, u8 Offset)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+	
+	ODM_AcquireSpinLock( pDM_Odm, RT_IQK_SPINLOCK);
+	if(pDM_Odm->RFCalibrateInfo.bIQKInProgress == _TRUE)
+		DBG_871X_LEVEL(_drv_err_, "%s, %d, IQK may race condition\n", __func__,__LINE__);
+	ODM_ReleaseSpinLock( pDM_Odm, RT_IQK_SPINLOCK);
+	padapter->HalFunc.set_bwmode_handler(padapter, Bandwidth, Offset);
+	
+}
+
+void	rtw_hal_set_chan(_adapter *padapter, u8 channel)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+	
+	ODM_AcquireSpinLock( pDM_Odm, RT_IQK_SPINLOCK);
+	if(pDM_Odm->RFCalibrateInfo.bIQKInProgress == _TRUE)
+		DBG_871X_LEVEL(_drv_err_, "%s, %d, IQK may race condition\n", __func__,__LINE__);
+	ODM_ReleaseSpinLock( pDM_Odm, RT_IQK_SPINLOCK);
+	padapter->HalFunc.set_channel_handler(padapter, channel);	
+}
+
+void	rtw_hal_set_chnl_bw(_adapter *padapter, u8 channel, CHANNEL_WIDTH Bandwidth, u8 Offset40, u8 Offset80)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+	
+	ODM_AcquireSpinLock( pDM_Odm, RT_IQK_SPINLOCK);
+	if(pDM_Odm->RFCalibrateInfo.bIQKInProgress == _TRUE)
+		DBG_871X_LEVEL(_drv_err_, "%s, %d, IQK may race condition\n", __func__,__LINE__);
+	ODM_ReleaseSpinLock( pDM_Odm, RT_IQK_SPINLOCK);
+	padapter->HalFunc.set_chnl_bw_handler(padapter, channel, Bandwidth, Offset40, Offset80);	
+}
+
+void	rtw_hal_set_tx_power_level(_adapter *padapter, u8 channel)
+{
+	if(padapter->HalFunc.set_tx_power_level_handler)
+		padapter->HalFunc.set_tx_power_level_handler(padapter, channel);
+}
+
+void	rtw_hal_get_tx_power_level(_adapter *padapter, s32 *powerlevel)
+{
+	if(padapter->HalFunc.get_tx_power_level_handler)
+		padapter->HalFunc.get_tx_power_level_handler(padapter, powerlevel);
+}
+
+void	rtw_hal_dm_watchdog(_adapter *padapter)
+{
+	if (!is_primary_adapter(padapter))
+		return;
+
+	padapter->HalFunc.hal_dm_watchdog(padapter);
+	
+}
+
+#ifdef CONFIG_LPS_LCLK_WD_TIMER
+void	rtw_hal_dm_watchdog_in_lps(_adapter *padapter)
+{
+#if defined(CONFIG_CONCURRENT_MODE)
+	if (padapter->iface_type != IFACE_PORT0)
+		return;
+#endif	
+
+	if (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode ==_TRUE ) {
+		padapter->HalFunc.hal_dm_watchdog_in_lps(padapter);//this fuction caller is in interrupt context				 	
+	}
+}
+#endif
+
+void rtw_hal_bcn_related_reg_setting(_adapter *padapter)
+{	
+	padapter->HalFunc.SetBeaconRelatedRegistersHandler(padapter);	
+}
+
+
+#ifdef CONFIG_ANTENNA_DIVERSITY
+u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
+{
+	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+	int i;
+
+	if (!padapter->HalFunc.AntDivBeforeLinkHandler)
+		return _FALSE;
+
+	for (i = 0; i < dvobj->iface_nums; i++) {
+		if (rtw_linked_check(dvobj->padapters[i]))
+			return _FALSE;
+	}
+
+	return padapter->HalFunc.AntDivBeforeLinkHandler(padapter);
+}
+void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
+{
+	if(padapter->HalFunc.AntDivCompareHandler)
+		padapter->HalFunc.AntDivCompareHandler(padapter, dst, src);
+}
+#endif
+
+#ifdef CONFIG_HOSTAPD_MLME
+s32	rtw_hal_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
+{
+	if(padapter->HalFunc.hostap_mgnt_xmit_entry)
+		return padapter->HalFunc.hostap_mgnt_xmit_entry(padapter, pkt);
+	return _FAIL;
+}
+#endif //CONFIG_HOSTAPD_MLME
+
+#ifdef DBG_CONFIG_ERROR_DETECT
+void	rtw_hal_sreset_init(_adapter *padapter)
+{
+	padapter->HalFunc.sreset_init_value(padapter); 
+}
+void rtw_hal_sreset_reset(_adapter *padapter)
+{
+	padapter = GET_PRIMARY_ADAPTER(padapter);
+	padapter->HalFunc.silentreset(padapter);
+}
+
+void rtw_hal_sreset_reset_value(_adapter *padapter)
+{
+	padapter->HalFunc.sreset_reset_value(padapter);
+}
+
+void rtw_hal_sreset_xmit_status_check(_adapter *padapter)
+{
+	if (!is_primary_adapter(padapter))
+		return;
+
+	padapter->HalFunc.sreset_xmit_status_check(padapter);		
+}
+void rtw_hal_sreset_linked_status_check(_adapter *padapter)
+{
+	if (!is_primary_adapter(padapter))
+		return;
+	padapter->HalFunc.sreset_linked_status_check(padapter);	
+}
+u8   rtw_hal_sreset_get_wifi_status(_adapter *padapter)
+{	
+	return padapter->HalFunc.sreset_get_wifi_status(padapter);
+}
+
+bool rtw_hal_sreset_inprogress(_adapter *padapter)
+{
+	padapter = GET_PRIMARY_ADAPTER(padapter);
+	return padapter->HalFunc.sreset_inprogress(padapter);
+}
+#endif	//DBG_CONFIG_ERROR_DETECT
+
+#ifdef CONFIG_IOL
+int rtw_hal_iol_cmd(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
+{
+	if(adapter->HalFunc.IOL_exec_cmds_sync)
+		return adapter->HalFunc.IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms,bndy_cnt);
+	return _FAIL;
+}
+#endif
+
+#ifdef CONFIG_XMIT_THREAD_MODE
+s32 rtw_hal_xmit_thread_handler(_adapter *padapter)
+{	
+	return padapter->HalFunc.xmit_thread_handler(padapter);
+}
+#endif
+
+void rtw_hal_notch_filter(_adapter *adapter, bool enable)
+{
+	if(adapter->HalFunc.hal_notch_filter)
+		adapter->HalFunc.hal_notch_filter(adapter,enable);		
+}
+
+bool rtw_hal_c2h_valid(_adapter *adapter, u8 *buf)
+{
+	HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter);
+	HAL_VERSION *hal_ver = &HalData->VersionID;
+	bool ret = _FAIL;
+
+	if (IS_8188E(*hal_ver)) {
+		ret = c2h_evt_valid((struct c2h_evt_hdr *)buf);
+	} else if(IS_8192E(*hal_ver) || IS_8812_SERIES(*hal_ver) || IS_8821_SERIES(*hal_ver) || IS_8723B_SERIES(*hal_ver)) {
+		ret = c2h_evt_valid((struct c2h_evt_hdr_88xx*)buf);
+	} else {
+		rtw_warn_on(1);
+	}
+
+	return ret;
+}
+
+s32 rtw_hal_c2h_evt_read(_adapter *adapter, u8 *buf)
+{
+	HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter);
+	HAL_VERSION *hal_ver = &HalData->VersionID;
+	s32 ret = _FAIL;
+
+	if (IS_8188E(*hal_ver)) {
+		ret = c2h_evt_read(adapter, buf);
+	} else if(IS_8192E(*hal_ver) || IS_8812_SERIES(*hal_ver) || IS_8821_SERIES(*hal_ver) || IS_8723B_SERIES(*hal_ver)) {
+		ret = c2h_evt_read_88xx(adapter, buf);
+	} else {
+		rtw_warn_on(1);
+	}
+
+	return ret;
+}
+
+s32 rtw_hal_c2h_handler(_adapter *adapter, u8 *c2h_evt)
+{
+	s32 ret = _FAIL;
+	if (adapter->HalFunc.c2h_handler)
+		ret = adapter->HalFunc.c2h_handler(adapter, c2h_evt);
+	return ret;
+}
+
+c2h_id_filter rtw_hal_c2h_id_filter_ccx(_adapter *adapter)
+{	
+	return adapter->HalFunc.c2h_id_filter_ccx;
+}
+
+s32 rtw_hal_is_disable_sw_channel_plan(PADAPTER padapter)
+{
+	return GET_HAL_DATA(padapter)->bDisableSWChannelPlan;
+}
+
+s32 rtw_hal_macid_sleep(PADAPTER padapter, u8 macid)
+{
+	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
+	u8 support;
+
+	support = _FALSE;
+	rtw_hal_get_def_var(padapter, HAL_DEF_MACID_SLEEP, &support);
+	if (_FALSE == support)
+		return _FAIL;
+
+	if (macid >= macid_ctl->num) {
+		DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT": Invalid macid(%u)\n",
+			FUNC_ADPT_ARG(padapter), macid);
+		return _FAIL;
+	}
+
+	rtw_hal_set_hwreg(padapter, HW_VAR_MACID_SLEEP, &macid);
+
+	return _SUCCESS;
+}
+
+s32 rtw_hal_macid_wakeup(PADAPTER padapter, u8 macid)
+{
+	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
+	u8 support;
+
+	support = _FALSE;
+	rtw_hal_get_def_var(padapter, HAL_DEF_MACID_SLEEP, &support);
+	if (_FALSE == support)
+		return _FAIL;
+
+	if (macid >= macid_ctl->num) {
+		DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT": Invalid macid(%u)\n",
+			FUNC_ADPT_ARG(padapter), macid);
+		return _FAIL;
+	}
+
+	rtw_hal_set_hwreg(padapter, HW_VAR_MACID_WAKEUP, &macid);
+
+	return _SUCCESS;
+}
+
+s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
+{
+	_adapter *pri_adapter = GET_PRIMARY_ADAPTER(padapter);
+
+	if (pri_adapter->bFWReady == _TRUE)
+		return padapter->HalFunc.fill_h2c_cmd(padapter, ElementID, CmdLen, pCmdBuffer);
+	else if (padapter->registrypriv.mp_mode == 0)
+		DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" FW doesn't exit when no MP mode, by pass H2C id:0x%02x\n"
+			, FUNC_ADPT_ARG(padapter), ElementID);
+	return _FAIL;
+}
+
+void rtw_hal_fill_fake_txdesc(_adapter* padapter, u8* pDesc, u32 BufferLen,
+		u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame)
+{
+	padapter->HalFunc.fill_fake_txdesc(padapter, pDesc, BufferLen,IsPsPoll, IsBTQosNull, bDataFrame);
+
+}
+u8 rtw_hal_get_txbuff_rsvd_page_num(_adapter *adapter, bool wowlan)
+{
+	return adapter->HalFunc.hal_get_tx_buff_rsvd_page_num(adapter, wowlan);
+}
+
+#ifdef CONFIG_GPIO_API
+void rtw_hal_update_hisr_hsisr_ind(_adapter *padapter, u32 flag)
+{
+	if (padapter->HalFunc.update_hisr_hsisr_ind)
+		padapter->HalFunc.update_hisr_hsisr_ind(padapter, flag);
+}
+#endif
+
+void rtw_hal_fw_correct_bcn(_adapter *padapter)
+{
+	if (padapter->HalFunc.fw_correct_bcn)
+		padapter->HalFunc.fw_correct_bcn(padapter);
+}
+
+#define rtw_hal_error_msg(ops_fun)		\
+	DBG_871X_LEVEL(_drv_always_, "### %s - Error : Please hook HalFunc.%s ###\n",__FUNCTION__,ops_fun)
+
+u8 rtw_hal_ops_check(_adapter *padapter)
+{	
+	u8 ret = _SUCCESS;
+#if 1
+	/*** initialize section ***/
+	if (NULL == padapter->HalFunc.read_chip_version) {
+		rtw_hal_error_msg("read_chip_version");
+		ret = _FAIL;
+	}	
+	if (NULL == padapter->HalFunc.init_default_value) {
+		rtw_hal_error_msg("init_default_value");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.intf_chip_configure) {
+		rtw_hal_error_msg("intf_chip_configure");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.read_adapter_info) {
+		rtw_hal_error_msg("read_adapter_info");
+		ret = _FAIL;
+	}
+
+	if (NULL == padapter->HalFunc.hal_power_on) {		
+		rtw_hal_error_msg("hal_power_on");
+		ret = _FAIL;
+	}	
+	if (NULL == padapter->HalFunc.hal_power_off) {
+		rtw_hal_error_msg("hal_power_off");
+		ret = _FAIL;
+	}
+	
+	if (NULL == padapter->HalFunc.hal_init) {
+		rtw_hal_error_msg("hal_init");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.hal_deinit) {
+		rtw_hal_error_msg("hal_deinit");
+		ret = _FAIL;
+	}
+	
+	/*** xmit section ***/
+	if (NULL == padapter->HalFunc.init_xmit_priv) {
+		rtw_hal_error_msg("init_xmit_priv");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.free_xmit_priv) {
+		rtw_hal_error_msg("free_xmit_priv");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.hal_xmit) {
+		rtw_hal_error_msg("hal_xmit");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.mgnt_xmit) {
+		rtw_hal_error_msg("mgnt_xmit");
+		ret = _FAIL;
+	}
+	#ifdef CONFIG_XMIT_THREAD_MODE
+	if (NULL == padapter->HalFunc.xmit_thread_handler) {
+		rtw_hal_error_msg("xmit_thread_handler");
+		ret = _FAIL;
+	}
+	#endif
+	if (NULL == padapter->HalFunc.hal_xmitframe_enqueue) {
+		rtw_hal_error_msg("hal_xmitframe_enqueue");
+		ret = _FAIL;
+	}
+	#if defined(CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
+	#ifndef CONFIG_SDIO_TX_TASKLET
+	if (NULL == padapter->HalFunc.run_thread) {
+		rtw_hal_error_msg("run_thread");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.cancel_thread) {
+		rtw_hal_error_msg("cancel_thread");
+		ret = _FAIL;
+	}
+	#endif
+	#endif
+	
+	/*** recv section ***/
+	if (NULL == padapter->HalFunc.init_recv_priv) {
+		rtw_hal_error_msg("init_recv_priv");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.free_recv_priv) {
+		rtw_hal_error_msg("free_recv_priv");
+		ret = _FAIL;
+	}
+	#if defined(CONFIG_USB_HCI) || defined (CONFIG_PCI_HCI)
+	if (NULL == padapter->HalFunc.inirp_init) {
+		rtw_hal_error_msg("inirp_init");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.inirp_deinit) {
+		rtw_hal_error_msg("inirp_deinit");
+		ret = _FAIL;
+	}
+	#endif //#if defined(CONFIG_USB_HCI) || defined (CONFIG_PCI_HCI)
+	
+	
+	/*** interrupt hdl section ***/
+	#if defined(CONFIG_PCI_HCI)
+	if (NULL == padapter->HalFunc.irp_reset) {
+		rtw_hal_error_msg("irp_reset");
+		ret = _FAIL;
+	}
+	#endif/*#if defined(CONFIG_PCI_HCI)*/
+	#if (defined(CONFIG_PCI_HCI)) || (defined(CONFIG_USB_HCI) && defined(CONFIG_SUPPORT_USB_INT))
+	if (NULL == padapter->HalFunc.interrupt_handler) {
+		rtw_hal_error_msg("interrupt_handler");
+		ret = _FAIL;
+	}
+	#endif /*#if (defined(CONFIG_PCI_HCI)) || (defined(CONFIG_USB_HCI) && defined(CONFIG_SUPPORT_USB_INT))*/
+
+	#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)	
+	if (NULL == padapter->HalFunc.enable_interrupt) {
+		rtw_hal_error_msg("enable_interrupt");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.disable_interrupt) {
+		rtw_hal_error_msg("disable_interrupt");
+		ret = _FAIL;
+	}
+	#endif //defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
+		
+	
+	/*** DM section ***/
+	if (NULL == padapter->HalFunc.dm_init) {
+		rtw_hal_error_msg("dm_init");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.dm_deinit) {
+		rtw_hal_error_msg("dm_deinit");
+		ret = _FAIL;
+	}	
+	if (NULL == padapter->HalFunc.hal_dm_watchdog) {
+		rtw_hal_error_msg("hal_dm_watchdog");
+		ret = _FAIL;
+	}
+	#ifdef CONFIG_LPS_LCLK_WD_TIMER
+	if (NULL == padapter->HalFunc.hal_dm_watchdog_in_lps) {
+		rtw_hal_error_msg("hal_dm_watchdog_in_lps");
+		ret = _FAIL;
+	}
+	#endif
+
+	/*** xxx section ***/
+	if (NULL == padapter->HalFunc.set_bwmode_handler) {
+		rtw_hal_error_msg("set_bwmode_handler");
+		ret = _FAIL;
+	}
+
+	if (NULL == padapter->HalFunc.set_channel_handler) {
+		rtw_hal_error_msg("set_channel_handler");
+		ret = _FAIL;
+	}
+
+	if (NULL == padapter->HalFunc.set_chnl_bw_handler) {
+		rtw_hal_error_msg("set_chnl_bw_handler");
+		ret = _FAIL;
+	}	
+	
+	if (NULL == padapter->HalFunc.SetHwRegHandler) {
+		rtw_hal_error_msg("SetHwRegHandler");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.GetHwRegHandler) {
+		rtw_hal_error_msg("GetHwRegHandler");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.GetHalDefVarHandler) {
+		rtw_hal_error_msg("GetHalDefVarHandler");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.SetHalDefVarHandler) {
+		rtw_hal_error_msg("SetHalDefVarHandler");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.GetHalODMVarHandler) {
+		rtw_hal_error_msg("GetHalODMVarHandler");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.SetHalODMVarHandler) {
+		rtw_hal_error_msg("SetHalODMVarHandler");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.UpdateRAMaskHandler) {
+		rtw_hal_error_msg("UpdateRAMaskHandler");
+		ret = _FAIL;
+	}
+	
+	if (NULL == padapter->HalFunc.SetBeaconRelatedRegistersHandler) {
+		rtw_hal_error_msg("SetBeaconRelatedRegistersHandler");
+		ret = _FAIL;
+	}
+
+	if (NULL == padapter->HalFunc.Add_RateATid) {
+		rtw_hal_error_msg("Add_RateATid");
+		ret = _FAIL;
+	}	
+
+	if (NULL == padapter->HalFunc.fill_h2c_cmd) {
+		rtw_hal_error_msg("fill_h2c_cmd");
+		ret = _FAIL;
+	}
+	#if defined(CONFIG_LPS) || defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+	if (NULL == padapter->HalFunc.fill_fake_txdesc) {
+		rtw_hal_error_msg("fill_fake_txdesc");
+		ret = _FAIL;
+	}
+	#endif
+	if (NULL == padapter->HalFunc.hal_get_tx_buff_rsvd_page_num) {
+		rtw_hal_error_msg("hal_get_tx_buff_rsvd_page_num");
+		ret = _FAIL;
+	}
+
+	#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+	#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+	if (NULL == padapter->HalFunc.clear_interrupt) {
+		rtw_hal_error_msg("clear_interrupt");
+		ret = _FAIL;
+	}
+	#endif
+	#endif /* CONFIG_WOWLAN */
+
+	if (NULL == padapter->HalFunc.fw_dl) {
+		rtw_hal_error_msg("fw_dl");
+		ret = _FAIL;
+	}
+
+	if ((IS_HARDWARE_TYPE_8814A(padapter)
+		|| IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8822BS(padapter))
+		&& NULL == padapter->HalFunc.fw_correct_bcn) {
+		rtw_hal_error_msg("fw_correct_bcn");
+		ret = _FAIL;
+	}
+	
+	
+	/*** SReset section ***/
+	#ifdef DBG_CONFIG_ERROR_DETECT		
+	if (NULL == padapter->HalFunc.sreset_init_value) {
+		rtw_hal_error_msg("sreset_init_value");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.sreset_reset_value) {
+		rtw_hal_error_msg("sreset_reset_value");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.silentreset) {
+		rtw_hal_error_msg("silentreset");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.sreset_xmit_status_check) {
+		rtw_hal_error_msg("sreset_xmit_status_check");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.sreset_linked_status_check) {
+		rtw_hal_error_msg("sreset_linked_status_check");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.sreset_get_wifi_status) {
+		rtw_hal_error_msg("sreset_get_wifi_status");
+		ret = _FAIL;
+	}
+	if (NULL == padapter->HalFunc.sreset_inprogress) {
+		rtw_hal_error_msg("sreset_inprogress");
+		ret = _FAIL;
+	}
+	#endif  //#ifdef DBG_CONFIG_ERROR_DETECT
+
+#endif
+	return  ret;
+}
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_mp.c b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_mp.c
new file mode 100644
index 000000000..68e3fc4b1
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_mp.c
@@ -0,0 +1,1799 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#define _HAL_MP_C_
+#ifdef CONFIG_MP_INCLUDED
+
+#ifdef CONFIG_RTL8188E
+#include <rtl8188e_hal.h>
+#endif
+#ifdef CONFIG_RTL8723B
+#include <rtl8723b_hal.h>
+#endif
+#ifdef CONFIG_RTL8192E
+#include <rtl8192e_hal.h>
+#endif
+#ifdef CONFIG_RTL8814A
+#include <rtl8814a_hal.h>
+#endif
+#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
+#include <rtl8812a_hal.h>
+#endif
+#ifdef CONFIG_RTL8703B
+#include <rtl8703b_hal.h>
+#endif
+#ifdef CONFIG_RTL8188F
+#include <rtl8188f_hal.h>
+#endif
+
+
+u8 MgntQuery_NssTxRate(u16 Rate)
+{
+	u8	NssNum = RF_TX_NUM_NONIMPLEMENT;
+	
+	if ((Rate >= MGN_MCS8 && Rate <= MGN_MCS15) || 
+		 (Rate >= MGN_VHT2SS_MCS0 && Rate <= MGN_VHT2SS_MCS9))
+		NssNum = RF_2TX;
+	else if ((Rate >= MGN_MCS16 && Rate <= MGN_MCS23) || 
+		 (Rate >= MGN_VHT3SS_MCS0 && Rate <= MGN_VHT3SS_MCS9))
+		NssNum = RF_3TX;
+	else if ((Rate >= MGN_MCS24 && Rate <= MGN_MCS31) || 
+		 (Rate >= MGN_VHT4SS_MCS0 && Rate <= MGN_VHT4SS_MCS9))
+		NssNum = RF_4TX;
+	else
+		NssNum = RF_1TX;
+		
+	return NssNum;
+}
+
+void hal_mpt_SwitchRfSetting(PADAPTER	pAdapter)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(pAdapter);
+	PMPT_CONTEXT		pMptCtx = &(pAdapter->mppriv.MptCtx);
+	u8				ChannelToSw = pMptCtx->MptChannelToSw;
+	ULONG				ulRateIdx = pMptCtx->MptRateIndex;
+	ULONG				ulbandwidth = pMptCtx->MptBandWidth;
+	
+	/* <20120525, Kordan> Dynamic mechanism for APK, asked by Dennis.*/
+	if (IS_HARDWARE_TYPE_8188ES(pAdapter) && (1 <= ChannelToSw && ChannelToSw <= 11) &&
+		(ulRateIdx == MPT_RATE_MCS0 || ulRateIdx == MPT_RATE_1M || ulRateIdx == MPT_RATE_6M)) {
+		pMptCtx->backup0x52_RF_A = (u1Byte)PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0);
+		pMptCtx->backup0x52_RF_B = (u1Byte)PHY_QueryRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0);
+		
+		if ((PlatformEFIORead4Byte(pAdapter, 0xF4)&BIT29) == BIT29) {
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, 0xB);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, 0xB);
+		} else {
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, 0xD);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, 0xD);
+		}
+	} else if (IS_HARDWARE_TYPE_8188EE(pAdapter)) { /* <20140903, VincentL> Asked by RF Eason and Edlu*/
+	
+		if (ChannelToSw == 3 && ulbandwidth == MPT_BW_40MHZ) {
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, 0xB); /*RF 0x52 = 0x0007E4BD*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, 0xB); /*RF 0x52 = 0x0007E4BD*/
+		} else {
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, 0x9); /*RF 0x52 = 0x0007E49D*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, 0x9); /*RF 0x52 = 0x0007E49D*/
+		}
+		
+	} else if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+		PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, pMptCtx->backup0x52_RF_A);
+		PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, pMptCtx->backup0x52_RF_B);
+	}
+}
+
+s32 hal_mpt_SetPowerTracking(PADAPTER padapter, u8 enable)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+
+
+	if (!netif_running(padapter->pnetdev)) {
+		RT_TRACE(_module_mp_, _drv_warning_, ("SetPowerTracking! Fail: interface not opened!\n"));
+		return _FAIL;
+	}
+
+	if (check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _FALSE) {
+		RT_TRACE(_module_mp_, _drv_warning_, ("SetPowerTracking! Fail: not in MP mode!\n"));
+		return _FAIL;
+	}
+	if (enable)
+		pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _TRUE;	
+	else
+		pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _FALSE;
+
+	return _SUCCESS;
+}
+
+void hal_mpt_GetPowerTracking(PADAPTER padapter, u8 *enable)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+
+
+	*enable = pDM_Odm->RFCalibrateInfo.TxPowerTrackControl;
+}
+
+
+void hal_mpt_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14)
+{
+	u32		TempVal = 0, TempVal2 = 0, TempVal3 = 0;
+	u32		CurrCCKSwingVal = 0, CCKSwingIndex = 12;
+	u8		i;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	
+	PMPT_CONTEXT		pMptCtx = &(Adapter->mppriv.MptCtx);
+	u1Byte				u1Channel = pHalData->CurrentChannel;
+	ULONG				ulRateIdx = pMptCtx->MptRateIndex;
+	u1Byte				DataRate = 0xFF;
+
+	DataRate = MptToMgntRate(ulRateIdx);
+	
+	if (u1Channel == 14 && IS_CCK_RATE(DataRate))
+		pHalData->bCCKinCH14 = TRUE;
+	else
+		pHalData->bCCKinCH14 = FALSE;	
+
+	if (IS_HARDWARE_TYPE_8703B(Adapter)) {
+			if ((u1Channel == 14) && IS_CCK_RATE(DataRate)) {
+				/* Channel 14 in CCK, need to set 0xA26~0xA29 to 0 for 8703B */ 
+				PHY_SetBBReg(Adapter, rCCK0_TxFilter2, bMaskHWord, 0);
+				PHY_SetBBReg(Adapter, rCCK0_DebugPort, bMaskLWord, 0);
+
+				RT_TRACE(_module_mp_, DBG_LOUD, ("MPT_CCKTxPowerAdjust 8703B CCK in Channel %u\n", u1Channel));
+			} else {
+				/* Normal setting for 8703B, just recover to the default setting. */
+				/* This hardcore values reference from the parameter which BB team gave. */
+				for (i = 0 ; i < 2 ; ++i)
+					PHY_SetBBReg(Adapter, pHalData->RegForRecover[i].offset, bMaskDWord, pHalData->RegForRecover[i].value);
+
+				RT_TRACE(_module_mp_, DBG_LOUD, ("MPT_CCKTxPowerAdjust 8703B in Channel %u restore to default setting\n", u1Channel));
+			}
+	} else if (IS_HARDWARE_TYPE_8188F(Adapter)) {
+		/* No difference between CCK in CH14 and others, no need to change TX filter */
+	} else {
+
+		/* get current cck swing value and check 0xa22 & 0xa23 later to match the table.*/
+		CurrCCKSwingVal = read_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord);
+
+		if (!pHalData->bCCKinCH14) {
+			/* Readback the current bb cck swing value and compare with the table to */
+			/* get the current swing index */
+			for (i = 0; i < CCK_TABLE_SIZE; i++) {
+				if (((CurrCCKSwingVal&0xff) == (u32)CCKSwingTable_Ch1_Ch13[i][0]) &&
+					(((CurrCCKSwingVal&0xff00)>>8) == (u32)CCKSwingTable_Ch1_Ch13[i][1])) {
+					CCKSwingIndex = i;
+					RT_TRACE(_module_mp_, DBG_LOUD, ("Ch1~13, Current reg0x%x = 0x%lx, CCKSwingIndex=0x%x\n",
+						(rCCK0_TxFilter1+2), CurrCCKSwingVal, CCKSwingIndex));
+					break;
+				}
+			}
+
+		/*Write 0xa22 0xa23*/
+		TempVal = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][0] +
+				(CCKSwingTable_Ch1_Ch13[CCKSwingIndex][1]<<8);
+
+
+		/*Write 0xa24 ~ 0xa27*/
+		TempVal2 = 0;
+		TempVal2 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][2] +
+				(CCKSwingTable_Ch1_Ch13[CCKSwingIndex][3]<<8) +
+				(CCKSwingTable_Ch1_Ch13[CCKSwingIndex][4]<<16) +
+				(CCKSwingTable_Ch1_Ch13[CCKSwingIndex][5]<<24);
+
+		/*Write 0xa28  0xa29*/
+		TempVal3 = 0;
+		TempVal3 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][6] +
+				(CCKSwingTable_Ch1_Ch13[CCKSwingIndex][7]<<8);
+	}  else {
+		for (i = 0; i < CCK_TABLE_SIZE; i++) {
+			if (((CurrCCKSwingVal&0xff) == (u32)CCKSwingTable_Ch14[i][0]) &&
+				(((CurrCCKSwingVal&0xff00)>>8) == (u32)CCKSwingTable_Ch14[i][1])) {
+				CCKSwingIndex = i;
+				RT_TRACE(_module_mp_, DBG_LOUD, ("Ch14, Current reg0x%x = 0x%lx, CCKSwingIndex=0x%x\n",
+					(rCCK0_TxFilter1+2), CurrCCKSwingVal, CCKSwingIndex));
+				break;
+			}
+		}
+
+		/*Write 0xa22 0xa23*/
+		TempVal = CCKSwingTable_Ch14[CCKSwingIndex][0] +
+				(CCKSwingTable_Ch14[CCKSwingIndex][1]<<8);
+
+		/*Write 0xa24 ~ 0xa27*/
+		TempVal2 = 0;
+		TempVal2 = CCKSwingTable_Ch14[CCKSwingIndex][2] +
+				(CCKSwingTable_Ch14[CCKSwingIndex][3]<<8) +
+				(CCKSwingTable_Ch14[CCKSwingIndex][4]<<16) +
+				(CCKSwingTable_Ch14[CCKSwingIndex][5]<<24);
+
+		/*Write 0xa28  0xa29*/
+		TempVal3 = 0;
+		TempVal3 = CCKSwingTable_Ch14[CCKSwingIndex][6] +
+				(CCKSwingTable_Ch14[CCKSwingIndex][7]<<8);
+	}
+
+	write_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord, TempVal);
+	write_bbreg(Adapter, rCCK0_TxFilter2, bMaskDWord, TempVal2);
+	write_bbreg(Adapter, rCCK0_DebugPort, bMaskLWord, TempVal3);
+
+	}
+
+}
+
+void hal_mpt_SetChannel(PADAPTER pAdapter)
+{
+	u8 eRFPath;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+	struct mp_priv	*pmp = &pAdapter->mppriv;
+	u8		channel = pmp->channel;
+	u8		bandwidth = pmp->bandwidth;
+	u8		rate = pmp->rateidx;
+
+	hal_mpt_SwitchRfSetting(pAdapter);
+	
+	SelectChannel(pAdapter, channel);
+	
+	pHalData->bSwChnl = _TRUE;
+	pHalData->bSetChnlBW = _TRUE;
+	rtw_hal_set_chnl_bw(pAdapter, channel, bandwidth, 0, 0);
+
+	hal_mpt_CCKTxPowerAdjust(pAdapter, pHalData->bCCKinCH14);
+
+}
+
+/*
+ * Notice
+ *	Switch bandwitdth may change center frequency(channel)
+ */
+void hal_mpt_SetBandwidth(PADAPTER pAdapter)
+{
+	struct mp_priv *pmp = &pAdapter->mppriv;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	
+	u8		channel = pmp->channel;
+	u8		bandwidth = pmp->bandwidth;
+	
+	SetBWMode(pAdapter, pmp->bandwidth, pmp->prime_channel_offset);
+	pHalData->bSwChnl = _TRUE;
+	pHalData->bSetChnlBW = _TRUE;
+	rtw_hal_set_chnl_bw(pAdapter, channel, bandwidth, 0, 0);
+	
+	hal_mpt_SwitchRfSetting(pAdapter);
+}
+
+void mpt_SetTxPower_Old(PADAPTER pAdapter, MPT_TXPWR_DEF Rate, u8 *pTxPower)
+{
+	RT_TRACE(_module_mp_, DBG_LOUD, ("===>mpt_SetTxPower_Old(): Case = %d\n", Rate));
+	switch (Rate) {
+	case MPT_CCK:
+			{
+			u4Byte	TxAGC = 0, pwr = 0;
+			u1Byte	rf;
+
+			pwr = pTxPower[ODM_RF_PATH_A];
+			if (pwr < 0x3f) {
+				TxAGC = (pwr<<16)|(pwr<<8)|(pwr);
+				PHY_SetBBReg(pAdapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, pTxPower[ODM_RF_PATH_A]);
+				PHY_SetBBReg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, TxAGC);
+			}
+			pwr = pTxPower[ODM_RF_PATH_B];
+			if (pwr < 0x3f) {
+				TxAGC = (pwr<<16)|(pwr<<8)|(pwr);
+				PHY_SetBBReg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, pTxPower[ODM_RF_PATH_B]);
+				PHY_SetBBReg(pAdapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, TxAGC);
+			}
+		    
+			} break;
+
+	case MPT_OFDM_AND_HT:
+			{
+			u4Byte	TxAGC = 0;
+			u1Byte	pwr = 0, rf;
+			
+			pwr = pTxPower[0];
+			if (pwr < 0x3f) {
+				TxAGC |= ((pwr<<24)|(pwr<<16)|(pwr<<8)|pwr);
+				DBG_871X("HT Tx-rf(A) Power = 0x%x\n", TxAGC);
+				
+				PHY_SetBBReg(pAdapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC);
+			}
+			TxAGC = 0;
+			pwr = pTxPower[1];
+			if (pwr < 0x3f) {
+				TxAGC |= ((pwr<<24)|(pwr<<16)|(pwr<<8)|pwr);
+				DBG_871X("HT Tx-rf(B) Power = 0x%x\n", TxAGC);
+				
+				PHY_SetBBReg(pAdapter, rTxAGC_B_Rate18_06, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_B_Rate54_24, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_B_Mcs03_Mcs00, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_B_Mcs07_Mcs04, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_B_Mcs11_Mcs08, bMaskDWord, TxAGC);
+				PHY_SetBBReg(pAdapter, rTxAGC_B_Mcs15_Mcs12, bMaskDWord, TxAGC);
+			}
+			} break;
+
+	default:
+		break;
+	}	
+		DBG_871X("<===mpt_SetTxPower_Old()\n");
+}
+
+
+
+void 
+mpt_SetTxPower(
+		PADAPTER		pAdapter,
+		MPT_TXPWR_DEF	Rate,
+		pu1Byte	pTxPower
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+
+	u1Byte path = 0 , i = 0, MaxRate = MGN_6M;
+	u1Byte StartPath = ODM_RF_PATH_A, EndPath = ODM_RF_PATH_B;
+	
+	if (IS_HARDWARE_TYPE_8814A(pAdapter))
+		EndPath = ODM_RF_PATH_D;
+
+	switch (Rate) {
+	case MPT_CCK:
+			{
+			u1Byte rate[] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M};
+
+			for (path = StartPath; path <= EndPath; path++)
+				for (i = 0; i < sizeof(rate); ++i)
+					PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]);	
+			}
+			break;
+		
+	case MPT_OFDM:
+			{
+			u1Byte rate[] = {
+				MGN_6M, MGN_9M, MGN_12M, MGN_18M,
+				MGN_24M, MGN_36M, MGN_48M, MGN_54M,
+				};
+
+			for (path = StartPath; path <= EndPath; path++)
+				for (i = 0; i < sizeof(rate); ++i)
+					PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]);	
+			} break;
+		
+	case MPT_HT:
+			{
+			u1Byte rate[] = {
+			MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4,
+			MGN_MCS5, MGN_MCS6, MGN_MCS7, MGN_MCS8, MGN_MCS9,
+			MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14,
+			MGN_MCS15, MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19,
+			MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23, MGN_MCS24,
+			MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29,
+			MGN_MCS30, MGN_MCS31,
+			};
+			if (pHalData->rf_type == RF_3T3R)
+				MaxRate = MGN_MCS23;
+			else if (pHalData->rf_type == RF_2T2R)
+				MaxRate = MGN_MCS15;
+			else
+				MaxRate = MGN_MCS7;
+			
+			for (path = StartPath; path <= EndPath; path++) {
+				for (i = 0; i < sizeof(rate); ++i) {
+					if (rate[i] > MaxRate)
+						break;					
+				    PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]);
+				}
+			}
+			} break;
+		
+	case MPT_VHT:
+			{
+			u1Byte rate[] = {
+			MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4,
+			MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9,
+			MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4,
+			MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9,
+			MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4,
+			MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9,
+			MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4,
+			MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9,
+			};
+					
+			if (pHalData->rf_type == RF_3T3R)
+				MaxRate = MGN_VHT3SS_MCS9;
+			else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
+				MaxRate = MGN_VHT2SS_MCS9;
+			else
+				MaxRate = MGN_VHT1SS_MCS9;
+
+			for (path = StartPath; path <= EndPath; path++) {
+				for (i = 0; i < sizeof(rate); ++i) {
+					if (rate[i] > MaxRate)
+						break;	
+					PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]);
+				}
+			}
+			} break;
+			
+	default:
+			DBG_871X("<===mpt_SetTxPower: Illegal channel!!\n");
+			break;
+	}
+
+}
+
+
+void hal_mpt_SetTxPower(PADAPTER pAdapter)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+	PMPT_CONTEXT		pMptCtx = &(pAdapter->mppriv.MptCtx);
+	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
+
+	if (pHalData->rf_chip < RF_TYPE_MAX) {
+		if (IS_HARDWARE_TYPE_8188E(pAdapter) || 
+			IS_HARDWARE_TYPE_8723B(pAdapter) || 
+			IS_HARDWARE_TYPE_8192E(pAdapter) || 
+			IS_HARDWARE_TYPE_8703B(pAdapter) ||
+			IS_HARDWARE_TYPE_8188F(pAdapter)) {
+			u8 path = (pHalData->AntennaTxPath == ANTENNA_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B);
+
+			DBG_8192C("===> MPT_ProSetTxPower: Old\n");
+
+			RT_TRACE(_module_mp_, DBG_LOUD, ("===> MPT_ProSetTxPower[Old]:\n"));
+			mpt_SetTxPower_Old(pAdapter, MPT_CCK, pMptCtx->TxPwrLevel);		
+			mpt_SetTxPower_Old(pAdapter, MPT_OFDM_AND_HT, pMptCtx->TxPwrLevel);
+
+		} else {
+			DBG_871X("===> MPT_ProSetTxPower: Jaguar\n");
+			mpt_SetTxPower(pAdapter, MPT_CCK, pMptCtx->TxPwrLevel);
+			mpt_SetTxPower(pAdapter, MPT_OFDM, pMptCtx->TxPwrLevel);
+			mpt_SetTxPower(pAdapter, MPT_HT, pMptCtx->TxPwrLevel);
+			mpt_SetTxPower(pAdapter, MPT_VHT, pMptCtx->TxPwrLevel);
+
+			}
+	} else
+		DBG_8192C("RFChipID < RF_TYPE_MAX, the RF chip is not supported - %d\n", pHalData->rf_chip);
+
+	ODM_ClearTxPowerTrackingState(pDM_Odm);
+
+}
+
+
+void hal_mpt_SetDataRate(PADAPTER pAdapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	PMPT_CONTEXT		pMptCtx = &(pAdapter->mppriv.MptCtx);
+	u32 DataRate;
+	
+	DataRate = MptToMgntRate(pAdapter->mppriv.rateidx);
+	
+	hal_mpt_SwitchRfSetting(pAdapter);
+
+	hal_mpt_CCKTxPowerAdjust(pAdapter, pHalData->bCCKinCH14);
+#ifdef CONFIG_RTL8723B
+	if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter)) {
+		if (IS_CCK_RATE(DataRate)) {
+			if (pMptCtx->MptRfPath == ODM_RF_PATH_A)
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, 0xF, 0x6);	
+			else
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x71, 0xF, 0x6);
+		} else {
+			if (pMptCtx->MptRfPath == ODM_RF_PATH_A)
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, 0xF, 0xE);	
+			else
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x71, 0xF, 0xE);		
+		}
+	}
+	
+	if ((IS_HARDWARE_TYPE_8723BS(pAdapter) && 
+		  ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA90)))) {
+		if (pMptCtx->MptRfPath == ODM_RF_PATH_A)
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, 0xF, 0xE);	
+		else
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x71, 0xF, 0xE);			
+	}
+#endif	
+}
+
+
+#define RF_PATH_AB	22
+
+#ifdef CONFIG_RTL8814A
+VOID mpt_ToggleIG_8814A(PADAPTER	pAdapter)
+{
+	u1Byte Path = 0;
+	u4Byte IGReg = rA_IGI_Jaguar, IGvalue = 0;
+
+	for (Path; Path <= ODM_RF_PATH_D; Path++) {
+		switch (Path) {
+		case ODM_RF_PATH_B:
+			IGReg = rB_IGI_Jaguar;
+			break;
+		case ODM_RF_PATH_C:
+			IGReg = rC_IGI_Jaguar2;
+			break;
+		case ODM_RF_PATH_D:
+			IGReg = rD_IGI_Jaguar2;
+			break;
+		default:
+			IGReg = rA_IGI_Jaguar;
+			break;
+		}
+
+		IGvalue = PHY_QueryBBReg(pAdapter, IGReg, bMaskByte0);
+		PHY_SetBBReg(pAdapter, IGReg, bMaskByte0, IGvalue+2);	   
+		PHY_SetBBReg(pAdapter, IGReg, bMaskByte0, IGvalue);
+	}
+}
+
+VOID mpt_SetRFPath_8814A(PADAPTER	pAdapter)
+{
+
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	PMPT_CONTEXT	pMptCtx = &pAdapter->mppriv.MptCtx;
+	R_ANTENNA_SELECT_OFDM	*p_ofdm_tx;	/* OFDM Tx register */
+	R_ANTENNA_SELECT_CCK	*p_cck_txrx;
+
+	u8	ForcedDataRate = HwRateToMRate(pAdapter->mppriv.rateidx);
+	u8	HtStbcCap = pAdapter->registrypriv.stbc_cap;
+	/*/PRT_HIGH_THROUGHPUT		pHTInfo = GET_HT_INFO(pMgntInfo);*/
+	/*/PRT_VERY_HIGH_THROUGHPUT	pVHTInfo = GET_VHT_INFO(pMgntInfo);*/
+
+	u32	ulAntennaTx = pHalData->AntennaTxPath;
+	u32	ulAntennaRx = pHalData->AntennaRxPath;
+	u8	NssforRate = MgntQuery_NssTxRate(ForcedDataRate);
+
+	if (NssforRate == RF_2TX) {	
+		DBG_871X("===> SetAntenna 2T ForcedDataRate %d NssforRate %d AntennaTx %d\n", ForcedDataRate, NssforRate, ulAntennaTx);
+
+		switch (ulAntennaTx) {
+		case ANTENNA_BC:
+				pMptCtx->MptRfPath = ODM_RF_PATH_BC;
+				/*pHalData->ValidTxPath = 0x06; linux no use */
+				PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0000fff0, 0x106);	/*/ 0x940[15:4]=12'b0000_0100_0011*/
+				break;
+
+		case ANTENNA_CD:
+				pMptCtx->MptRfPath = ODM_RF_PATH_CD;
+				/*pHalData->ValidTxPath = 0x0C;*/
+				PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0000fff0, 0x40c);	/*/ 0x940[15:4]=12'b0000_0100_0011*/
+				break;
+		case ANTENNA_AB: default:
+				pMptCtx->MptRfPath = ODM_RF_PATH_AB;
+				/*pHalData->ValidTxPath = 0x03;*/
+				PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0000fff0, 0x043);	/*/ 0x940[15:4]=12'b0000_0100_0011*/
+				break;
+		}
+
+	} else if (NssforRate == RF_3TX) {
+				DBG_871X("===> SetAntenna 3T ForcedDataRate %d NssforRate %d AntennaTx %d\n", ForcedDataRate, NssforRate, ulAntennaTx);
+
+		switch (ulAntennaTx) {
+		case ANTENNA_BCD:
+				pMptCtx->MptRfPath = ODM_RF_PATH_BCD;
+				/*pHalData->ValidTxPath = 0x0e;*/
+				PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0fff0000, 0x90e);	/*/ 0x940[27:16]=12'b0010_0100_0111*/
+				break;
+
+		case ANTENNA_ABC: default:
+				pMptCtx->MptRfPath = ODM_RF_PATH_ABC;
+				/*pHalData->ValidTxPath = 0x0d;*/
+				PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0fff0000, 0x247);	/*/ 0x940[27:16]=12'b0010_0100_0111*/
+				break;
+		}
+
+	} else { /*/if(NssforRate == RF_1TX)*/
+		DBG_871X("===> SetAntenna 1T ForcedDataRate %d NssforRate %d AntennaTx %d\n", ForcedDataRate, NssforRate, ulAntennaTx);
+		switch (ulAntennaTx) {
+		case ANTENNA_B:
+				pMptCtx->MptRfPath = ODM_RF_PATH_B;
+				/*pHalData->ValidTxPath = 0x02;*/
+				PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0xf0000000, 0x4);			/*/ 0xa07[7:4] = 4'b0100*/
+				PHY_SetBBReg(pAdapter, rTxAnt_1Nsts_Jaguar2, 0xfff00000, 0x002);	/*/ 0x93C[31:20]=12'b0000_0000_0010*/
+				PHY_SetBBReg(pAdapter, rTxPath_Jaguar, 0xf0, 0x2);					/* 0x80C[7:4] = 4'b0010*/
+				break;
+
+		case ANTENNA_C:
+				pMptCtx->MptRfPath = ODM_RF_PATH_C;
+				/*pHalData->ValidTxPath = 0x04;*/
+				PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0xf0000000, 0x2);			/*/ 0xa07[7:4] = 4'b0010*/
+				PHY_SetBBReg(pAdapter, rTxAnt_1Nsts_Jaguar2, 0xfff00000, 0x004);	/*/ 0x93C[31:20]=12'b0000_0000_0100*/
+				PHY_SetBBReg(pAdapter, rTxPath_Jaguar, 0xf0, 0x4);					/*/ 0x80C[7:4] = 4'b0100*/
+				break;
+
+		case ANTENNA_D:
+				pMptCtx->MptRfPath = ODM_RF_PATH_D;
+				/*pHalData->ValidTxPath = 0x08;*/
+				PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0xf0000000, 0x1);			/*/ 0xa07[7:4] = 4'b0001*/
+				PHY_SetBBReg(pAdapter, rTxAnt_1Nsts_Jaguar2, 0xfff00000, 0x008);	/*/ 0x93C[31:20]=12'b0000_0000_1000*/
+				PHY_SetBBReg(pAdapter, rTxPath_Jaguar, 0xf0, 0x8);					/*/ 0x80C[7:4] = 4'b1000*/
+				break;
+
+		case ANTENNA_A: default:
+				pMptCtx->MptRfPath = ODM_RF_PATH_A;
+				/*pHalData->ValidTxPath = 0x01;*/
+				PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0xf0000000, 0x8);			/*/ 0xa07[7:4] = 4'b1000*/
+				PHY_SetBBReg(pAdapter, rTxAnt_1Nsts_Jaguar2, 0xfff00000, 0x001);	/*/ 0x93C[31:20]=12'b0000_0000_0001*/
+				PHY_SetBBReg(pAdapter, rTxPath_Jaguar, 0xf0, 0x1);					/*/ 0x80C[7:4] = 4'b0001*/
+				break;
+		}
+	}
+
+	switch (ulAntennaRx) {
+	case ANTENNA_A:
+			/*pHalData->ValidRxPath = 0x01;*/
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2);
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x11);
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3);
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0C000000, 0x0);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_A_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_C_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_D_0x0[19:16] = 1, Standby mode*/
+			/*/ CCA related PD_delay_th*/
+			PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5);
+			PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA);
+			break;
+
+	case ANTENNA_B:
+			/*pHalData->ValidRxPath = 0x02;*/
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2);
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x22);	
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3);
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0C000000, 0x1);	
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_C_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_D_0x0[19:16] = 1, Standby mode*/
+			/*/ CCA related PD_delay_th*/
+			PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5);
+			PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA);
+			break;
+
+	case ANTENNA_C:
+			/*pHalData->ValidRxPath = 0x04;*/
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2);
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x44);	
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3);
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0C000000, 0x2);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_D_0x0[19:16] = 1, Standby mode*/
+			/*/ CCA related PD_delay_th*/
+			PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5);
+			PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA);
+			break;
+
+	case ANTENNA_D:
+			/*pHalData->ValidRxPath = 0x08;*/
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2);
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x88);	
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3);
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0C000000, 0x3);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_C_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_D_0x0[19:16] = 3, RX mode*/
+			/*/ CCA related PD_delay_th*/
+			PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5);
+			PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA);
+			break;
+
+	case ANTENNA_BC: 
+			/*pHalData->ValidRxPath = 0x06;*/
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2);
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x66);
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3);
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0f000000, 0x6);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, Rx mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_D_0x0[19:16] = 1, Standby mode*/
+			/*/ CCA related PD_delay_th*/
+			PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5);
+			PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA);
+			break;
+
+	case ANTENNA_CD: 
+			/*pHalData->ValidRxPath = 0x0C;*/
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2);
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0xcc);
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3);
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0f000000, 0xB);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, Rx mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_D_0x0[19:16] = 3, RX mode*/
+			/*/ CCA related PD_delay_th*/
+			PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5);
+			PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA);
+			break;
+
+	case ANTENNA_BCD: 
+			/*pHalData->ValidRxPath = 0x0e;*/
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2);
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0xee);
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3);
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0f000000, 0x6);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_D_0x0[19:16] = 3, Rx mode*/
+			/*/ CCA related PD_delay_th*/
+			PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x3);
+			PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0x8);
+			break;
+
+	case ANTENNA_ABCD: 
+			/*pHalData->ValidRxPath = 0x0f;*/
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2);
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0xff);
+			PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3);
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0f000000, 0x1);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_A_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, RX mode*/
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_D_0x0[19:16] = 3, RX mode*/
+			/*/ CCA related PD_delay_th*/
+			PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x3);
+			PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0x8);
+			break;
+
+	default:
+			RT_TRACE(_module_mp_, _drv_warning_, ("Unknown Rx antenna.\n"));
+			break;
+	}
+
+	PHY_Set_SecCCATH_by_RXANT_8814A(pAdapter, ulAntennaRx);
+
+	mpt_ToggleIG_8814A(pAdapter);
+	RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n"));
+}
+
+VOID
+mpt_SetSingleTone_8814A(
+	IN	PADAPTER	pAdapter,
+	IN	BOOLEAN	bSingleTone,
+	IN	BOOLEAN	bEnPMacTx)
+{
+
+	PMPT_CONTEXT	pMptCtx = &(pAdapter->mppriv.MptCtx);
+	u1Byte StartPath = ODM_RF_PATH_A,  EndPath = ODM_RF_PATH_A;
+	static u4Byte		regIG0 = 0, regIG1 = 0, regIG2 = 0, regIG3 = 0;
+
+	if (bSingleTone) {		
+		regIG0 = PHY_QueryBBReg(pAdapter, rA_TxScale_Jaguar, bMaskDWord);		/*/ 0xC1C[31:21]*/
+		regIG1 = PHY_QueryBBReg(pAdapter, rB_TxScale_Jaguar, bMaskDWord);		/*/ 0xE1C[31:21]*/
+		regIG2 = PHY_QueryBBReg(pAdapter, rC_TxScale_Jaguar2, bMaskDWord);	/*/ 0x181C[31:21]*/
+		regIG3 = PHY_QueryBBReg(pAdapter, rD_TxScale_Jaguar2, bMaskDWord);	/*/ 0x1A1C[31:21]*/
+
+		switch (pMptCtx->MptRfPath) {
+		case ODM_RF_PATH_A: case ODM_RF_PATH_B:
+		case ODM_RF_PATH_C: case ODM_RF_PATH_D:
+			StartPath = pMptCtx->MptRfPath;
+			EndPath = pMptCtx->MptRfPath;
+			break;
+		case ODM_RF_PATH_AB:
+			EndPath = ODM_RF_PATH_B;
+			break;
+		case ODM_RF_PATH_BC:
+			StartPath = ODM_RF_PATH_B;
+			EndPath = ODM_RF_PATH_C;
+			break;
+		case ODM_RF_PATH_ABC:
+			EndPath = ODM_RF_PATH_C;
+			break;
+		case ODM_RF_PATH_BCD:
+			StartPath = ODM_RF_PATH_B;
+			EndPath = ODM_RF_PATH_D;
+			break;
+		case ODM_RF_PATH_ABCD:
+			EndPath = ODM_RF_PATH_D;
+			break;
+		}
+
+		if (bEnPMacTx == FALSE) {
+			hal_mpt_SetOFDMContinuousTx(pAdapter, _TRUE);
+			issue_nulldata(pAdapter, NULL, 1, 3, 500);
+		}
+
+		PHY_SetBBReg(pAdapter, rCCAonSec_Jaguar, BIT1, 0x1); /*/ Disable CCA*/
+
+		for (StartPath; StartPath <= EndPath; StartPath++) {
+			PHY_SetRFReg(pAdapter, StartPath, RF_AC_Jaguar, 0xF0000, 0x2); /*/ Tx mode: RF0x00[19:16]=4'b0010 */
+			PHY_SetRFReg(pAdapter, StartPath, RF_AC_Jaguar, 0x1F, 0x0); /*/ Lowest RF gain index: RF_0x0[4:0] = 0*/
+
+			PHY_SetRFReg(pAdapter, StartPath, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO enabled*/
+		}
+
+		PHY_SetBBReg(pAdapter, rA_TxScale_Jaguar, 0xFFE00000, 0); /*/ 0xC1C[31:21]*/
+		PHY_SetBBReg(pAdapter, rB_TxScale_Jaguar, 0xFFE00000, 0); /*/ 0xE1C[31:21]*/
+		PHY_SetBBReg(pAdapter, rC_TxScale_Jaguar2, 0xFFE00000, 0); /*/ 0x181C[31:21]*/
+		PHY_SetBBReg(pAdapter, rD_TxScale_Jaguar2, 0xFFE00000, 0); /*/ 0x1A1C[31:21]*/
+		
+	} else {
+	
+		switch (pMptCtx->MptRfPath) {
+		case ODM_RF_PATH_A: case ODM_RF_PATH_B:
+		case ODM_RF_PATH_C: case ODM_RF_PATH_D:
+				StartPath = pMptCtx->MptRfPath;
+				EndPath = pMptCtx->MptRfPath;
+				break;
+		case ODM_RF_PATH_AB:
+				EndPath = ODM_RF_PATH_B;
+				break;
+		case ODM_RF_PATH_BC:
+				StartPath = ODM_RF_PATH_B;
+				EndPath = ODM_RF_PATH_C;
+				break;
+		case ODM_RF_PATH_ABC:
+				EndPath = ODM_RF_PATH_C;
+				break;
+		case ODM_RF_PATH_BCD:
+				StartPath = ODM_RF_PATH_B;
+				EndPath = ODM_RF_PATH_D;
+				break;
+		case ODM_RF_PATH_ABCD:
+				EndPath = ODM_RF_PATH_D;
+				break;
+		}
+		
+		for (StartPath; StartPath <= EndPath; StartPath++)
+			PHY_SetRFReg(pAdapter, StartPath, LNA_Low_Gain_3, BIT1, 0x0); /*// RF LO disabled*/
+
+		
+		PHY_SetBBReg(pAdapter, rCCAonSec_Jaguar, BIT1, 0x0); /* Enable CCA*/
+
+		if (bEnPMacTx == FALSE)
+			hal_mpt_SetOFDMContinuousTx(pAdapter, _FALSE);
+
+		PHY_SetBBReg(pAdapter, rA_TxScale_Jaguar, bMaskDWord, regIG0); /* 0xC1C[31:21]*/
+		PHY_SetBBReg(pAdapter, rB_TxScale_Jaguar, bMaskDWord, regIG1); /* 0xE1C[31:21]*/
+		PHY_SetBBReg(pAdapter, rC_TxScale_Jaguar2, bMaskDWord, regIG2); /* 0x181C[31:21]*/
+		PHY_SetBBReg(pAdapter, rD_TxScale_Jaguar2, bMaskDWord, regIG3); /* 0x1A1C[31:21]*/
+	}
+}
+
+#endif
+
+#if	defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
+void mpt_SetRFPath_8812A(PADAPTER pAdapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	PMPT_CONTEXT	pMptCtx = &pAdapter->mppriv.MptCtx;
+	u32		ulAntennaTx, ulAntennaRx;
+
+	ulAntennaTx = pHalData->AntennaTxPath;
+	ulAntennaRx = pHalData->AntennaRxPath;
+
+	switch (ulAntennaTx) {
+	case ANTENNA_A:
+			pMptCtx->MptRfPath = ODM_RF_PATH_A;
+			PHY_SetBBReg(pAdapter, rTxPath_Jaguar, bMaskLWord, 0x1111);
+			if (pHalData->RFEType == 3 && IS_HARDWARE_TYPE_8812(pAdapter))
+				PHY_SetBBReg(pAdapter, r_ANTSEL_SW_Jaguar, bMask_AntselPathFollow_Jaguar, 0x0);	 
+			break;
+	case ANTENNA_B:
+			pMptCtx->MptRfPath = ODM_RF_PATH_B;
+			PHY_SetBBReg(pAdapter, rTxPath_Jaguar, bMaskLWord, 0x2222);
+			if (pHalData->RFEType == 3 && IS_HARDWARE_TYPE_8812(pAdapter))
+				PHY_SetBBReg(pAdapter,	r_ANTSEL_SW_Jaguar, bMask_AntselPathFollow_Jaguar, 0x1);
+			break;
+	case ANTENNA_AB:
+			pMptCtx->MptRfPath = ODM_RF_PATH_AB;
+			PHY_SetBBReg(pAdapter, rTxPath_Jaguar, bMaskLWord, 0x3333);
+			if (pHalData->RFEType == 3 && IS_HARDWARE_TYPE_8812(pAdapter))
+				PHY_SetBBReg(pAdapter, r_ANTSEL_SW_Jaguar, bMask_AntselPathFollow_Jaguar, 0x0);
+			break;
+	default:
+			pMptCtx->MptRfPath = ODM_RF_PATH_AB;
+			DBG_871X("Unknown Tx antenna.\n");
+			break;
+	}
+
+	switch (ulAntennaRx) {
+			u32 reg0xC50 = 0;
+	case ANTENNA_A:
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x11);	
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, bCCK_RX_Jaguar, 0x0);	   
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, BIT19|BIT18|BIT17|BIT16, 0x3); 
+
+			/*/ <20121101, Kordan> To prevent gain table from not switched, asked by Ynlin.*/
+			reg0xC50 = PHY_QueryBBReg(pAdapter, rA_IGI_Jaguar, bMaskByte0);
+			PHY_SetBBReg(pAdapter, rA_IGI_Jaguar, bMaskByte0, reg0xC50+2);	   
+			PHY_SetBBReg(pAdapter, rA_IGI_Jaguar, bMaskByte0, reg0xC50);			
+			break;
+	case ANTENNA_B:
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x22);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1);/*/ RF_A_0x0[19:16] = 1, Standby mode */
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, bCCK_RX_Jaguar, 0x1);
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, BIT19|BIT18|BIT17|BIT16, 0x3); 
+
+			/*/ <20121101, Kordan> To prevent gain table from not switched, asked by Ynlin.*/
+			reg0xC50 = PHY_QueryBBReg(pAdapter, rB_IGI_Jaguar, bMaskByte0);
+			PHY_SetBBReg(pAdapter, rB_IGI_Jaguar, bMaskByte0, reg0xC50+2);	   
+			PHY_SetBBReg(pAdapter, rB_IGI_Jaguar, bMaskByte0, reg0xC50);						
+			break;
+	case ANTENNA_AB:
+			PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x33);	
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, Rx mode*/
+			PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, bCCK_RX_Jaguar, 0x0);	
+			break;
+	default:
+			DBG_871X("Unknown Rx antenna.\n");
+			break;
+	}
+	RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n"));
+}
+#endif
+
+
+#ifdef CONFIG_RTL8723B
+void mpt_SetRFPath_8723B(PADAPTER pAdapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	u32		ulAntennaTx, ulAntennaRx;
+	PMPT_CONTEXT	pMptCtx = &(pAdapter->mppriv.MptCtx);
+	PDM_ODM_T	pDM_Odm = &pHalData->odmpriv;
+	PODM_RF_CAL_T	pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
+
+	ulAntennaTx = pHalData->AntennaTxPath;
+	ulAntennaRx = pHalData->AntennaRxPath;
+
+	if (pHalData->rf_chip >= RF_TYPE_MAX) {
+		DBG_8192C("This RF chip ID is not supported\n");
+		return;
+	}
+
+	switch (pAdapter->mppriv.antenna_tx) {
+		u8 p = 0, i = 0;
+	case ANTENNA_A: /*/ Actually path S1  (Wi-Fi)*/
+			{
+			pMptCtx->MptRfPath = ODM_RF_PATH_A;			
+			PHY_SetBBReg(pAdapter, rS0S1_PathSwitch, BIT9|BIT8|BIT7, 0x0);
+			PHY_SetBBReg(pAdapter, 0xB2C, BIT31, 0x0); /* AGC Table Sel*/
+
+			/*/<20130522, Kordan> 0x51 and 0x71 should be set immediately after path switched, or they might be overwritten.*/
+			if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA90))
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B10E);
+			else
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B04E);
+
+
+			for (i = 0; i < 3; ++i) {
+				u4Byte offset = pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_A][i][0];
+				u4Byte data = pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_A][i][1];
+				
+				if (offset != 0) {
+					PHY_SetBBReg(pAdapter, offset, bMaskDWord, data);
+					DBG_8192C("Switch to S1 TxIQC(offset, data) = (0x%X, 0x%X)\n", offset, data);
+				}
+
+			}
+			for (i = 0; i < 2; ++i) {
+				u4Byte offset = pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_A][i][0];
+				u4Byte data = pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_A][i][1];
+				
+				if (offset != 0) {
+					PHY_SetBBReg(pAdapter, offset, bMaskDWord, data);					
+					DBG_8192C("Switch to S1 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data);
+				}
+			}
+			}
+			break;
+	case ANTENNA_B: /*/ Actually path S0 (BT)*/
+			{
+			u4Byte offset;
+			u4Byte data;
+			
+			pMptCtx->MptRfPath = ODM_RF_PATH_B;
+			PHY_SetBBReg(pAdapter, rS0S1_PathSwitch, BIT9|BIT8|BIT7, 0x5);
+			PHY_SetBBReg(pAdapter, 0xB2C, BIT31, 0x1); /*/ AGC Table Sel.*/
+				
+			/* <20130522, Kordan> 0x51 and 0x71 should be set immediately after path switched, or they might be overwritten.*/
+			if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA90))
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B10E);
+			else
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B04E);
+
+			for (i = 0; i < 3; ++i) {
+				/*/ <20130603, Kordan> Because BB suppors only 1T1R, we restore IQC  to S1 instead of S0.*/
+				offset = pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_A][i][0];
+				data = pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_B][i][1];
+				if (pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_B][i][0] != 0) {
+					PHY_SetBBReg(pAdapter, offset, bMaskDWord, data);
+					DBG_8192C("Switch to S0 TxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data);
+				}
+			}
+			/*/ <20130603, Kordan> Because BB suppors only 1T1R, we restore IQC to S1 instead of S0.*/
+			for (i = 0; i < 2; ++i) {
+				offset = pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_A][i][0];
+				data = pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_B][i][1];
+				
+				if (pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_B][i][0] != 0) {
+					PHY_SetBBReg(pAdapter, offset, bMaskDWord, data);
+					DBG_8192C("Switch to S0 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data);
+				}
+			}
+			}
+			break;
+	default:
+		pMptCtx->MptRfPath = RF_PATH_AB;
+		RT_TRACE(_module_mp_, _drv_notice_, ("Unknown Tx antenna.\n"));
+		break;
+	}
+	RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n"));
+}
+#endif
+
+#ifdef CONFIG_RTL8703B
+void mpt_SetRFPath_8703B(PADAPTER pAdapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	u4Byte					ulAntennaTx, ulAntennaRx;
+	PMPT_CONTEXT		pMptCtx = &(pAdapter->mppriv.MptCtx);
+	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
+	PODM_RF_CAL_T			pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo);
+
+	ulAntennaTx = pHalData->AntennaTxPath;
+	ulAntennaRx = pHalData->AntennaRxPath;
+
+	if (pHalData->rf_chip >= RF_TYPE_MAX) {
+		DBG_871X("This RF chip ID is not supported\n");
+		return;
+	}
+
+	switch (pAdapter->mppriv.antenna_tx) {
+		u1Byte p = 0, i = 0;
+
+	case ANTENNA_A: /* Actually path S1  (Wi-Fi) */
+				{
+				pMptCtx->MptRfPath = ODM_RF_PATH_A;			
+				PHY_SetBBReg(pAdapter, rS0S1_PathSwitch, BIT9|BIT8|BIT7, 0x0);
+				PHY_SetBBReg(pAdapter, 0xB2C, BIT31, 0x0); /* AGC Table Sel*/
+
+				for (i = 0; i < 3; ++i) {
+					u4Byte offset = pRFCalibrateInfo->TxIQC_8703B[i][0];
+					u4Byte data = pRFCalibrateInfo->TxIQC_8703B[i][1];
+
+					if (offset != 0) {
+						PHY_SetBBReg(pAdapter, offset, bMaskDWord, data);
+						DBG_871X("Switch to S1 TxIQC(offset, data) = (0x%X, 0x%X)\n", offset, data);
+					}
+
+				}
+				for (i = 0; i < 2; ++i) {
+					u4Byte offset = pRFCalibrateInfo->RxIQC_8703B[i][0];
+					u4Byte data = pRFCalibrateInfo->RxIQC_8703B[i][1];
+
+					if (offset != 0) {
+						PHY_SetBBReg(pAdapter, offset, bMaskDWord, data);					
+						DBG_871X("Switch to S1 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data);
+					}
+				}
+				}
+	break;
+	case ANTENNA_B: /* Actually path S0 (BT)*/
+				{
+				pMptCtx->MptRfPath = ODM_RF_PATH_B;
+				PHY_SetBBReg(pAdapter, rS0S1_PathSwitch, BIT9|BIT8|BIT7, 0x5);
+				PHY_SetBBReg(pAdapter, 0xB2C, BIT31, 0x1); /* AGC Table Sel */
+
+				for (i = 0; i < 3; ++i) {
+					u4Byte offset = pRFCalibrateInfo->TxIQC_8703B[i][0];
+					u4Byte data = pRFCalibrateInfo->TxIQC_8703B[i][1];
+
+					if (pRFCalibrateInfo->TxIQC_8703B[i][0] != 0) {
+						PHY_SetBBReg(pAdapter, offset, bMaskDWord, data);
+						DBG_871X("Switch to S0 TxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data);
+					}
+				}
+				for (i = 0; i < 2; ++i) {
+					u4Byte offset = pRFCalibrateInfo->RxIQC_8703B[i][0];
+					u4Byte data = pRFCalibrateInfo->RxIQC_8703B[i][1];
+
+					if (pRFCalibrateInfo->RxIQC_8703B[i][0] != 0) {
+						PHY_SetBBReg(pAdapter, offset, bMaskDWord, data);
+						DBG_871X("Switch to S0 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data);
+					}
+				}
+				}
+	break;
+	default:
+			pMptCtx->MptRfPath = RF_PATH_AB; 
+			RT_TRACE(_module_mp_, _drv_notice_, ("Unknown Tx antenna.\n"));
+	break;
+	}
+
+	RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n"));
+}
+#endif
+
+
+VOID mpt_SetRFPath_819X(PADAPTER	pAdapter)
+{
+	HAL_DATA_TYPE			*pHalData	= GET_HAL_DATA(pAdapter);
+	PMPT_CONTEXT		pMptCtx = &(pAdapter->mppriv.MptCtx);
+	u4Byte			ulAntennaTx, ulAntennaRx;
+	R_ANTENNA_SELECT_OFDM	*p_ofdm_tx;	/* OFDM Tx register */
+	R_ANTENNA_SELECT_CCK	*p_cck_txrx;
+	u1Byte		r_rx_antenna_ofdm = 0, r_ant_select_cck_val = 0;
+	u1Byte		chgTx = 0, chgRx = 0;
+	u4Byte		r_ant_sel_cck_val = 0, r_ant_select_ofdm_val = 0, r_ofdm_tx_en_val = 0;
+
+	ulAntennaTx = pHalData->AntennaTxPath;
+	ulAntennaRx = pHalData->AntennaRxPath;
+	
+	p_ofdm_tx = (R_ANTENNA_SELECT_OFDM *)&r_ant_select_ofdm_val;
+	p_cck_txrx = (R_ANTENNA_SELECT_CCK *)&r_ant_select_cck_val;
+
+	p_ofdm_tx->r_ant_ht1			= 0x1;
+	p_ofdm_tx->r_ant_ht2			= 0x2;/*Second TX RF path is A*/
+	p_ofdm_tx->r_ant_non_ht			= 0x3;/*/ 0x1+0x2=0x3 */
+
+	switch (ulAntennaTx) {
+	case ANTENNA_A:
+			p_ofdm_tx->r_tx_antenna		= 0x1;
+			r_ofdm_tx_en_val		= 0x1;
+			p_ofdm_tx->r_ant_l		= 0x1;
+			p_ofdm_tx->r_ant_ht_s1		= 0x1;
+			p_ofdm_tx->r_ant_non_ht_s1	= 0x1;
+			p_cck_txrx->r_ccktx_enable	= 0x8;
+			chgTx = 1;
+			/*/ From SD3 Willis suggestion !!! Set RF A=TX and B as standby*/
+			/*/if (IS_HARDWARE_TYPE_8192S(pAdapter))*/
+			{
+				PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2);
+				PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1);
+				r_ofdm_tx_en_val			= 0x3;
+				/*/ Power save*/
+				/*/cosa r_ant_select_ofdm_val = 0x11111111;*/
+				/*/ We need to close RFB by SW control*/
+			if (pHalData->rf_type == RF_2T2R) {
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0);
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 1);
+				PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1);
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 0);
+			}
+			}
+			pMptCtx->MptRfPath = ODM_RF_PATH_A;
+			break;
+	case ANTENNA_B:
+			p_ofdm_tx->r_tx_antenna		= 0x2;
+			r_ofdm_tx_en_val		= 0x2;
+			p_ofdm_tx->r_ant_l		= 0x2;
+			p_ofdm_tx->r_ant_ht_s1		= 0x2;
+			p_ofdm_tx->r_ant_non_ht_s1	= 0x2;
+			p_cck_txrx->r_ccktx_enable	= 0x4;
+			chgTx = 1;
+			/*/ From SD3 Willis suggestion !!! Set RF A as standby*/
+			/*/if (IS_HARDWARE_TYPE_8192S(pAdapter))*/
+			{
+				PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1);
+				PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2);
+
+				/*/ 2008/10/31 MH From SD3 Willi's suggestion. We must read RF 1T table.*/
+				/*/ 2009/01/08 MH From Sd3 Willis. We need to close RFA by SW control*/
+			if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_1T2R) {
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 1);
+				PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0);
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0);
+				/*/PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);*/
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 0);
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1);
+			}
+			}
+			pMptCtx->MptRfPath = ODM_RF_PATH_B;		
+			break;
+	case ANTENNA_AB:/*/ For 8192S*/
+			p_ofdm_tx->r_tx_antenna		= 0x3;
+			r_ofdm_tx_en_val		= 0x3;
+			p_ofdm_tx->r_ant_l		= 0x3;
+			p_ofdm_tx->r_ant_ht_s1		= 0x3;
+			p_ofdm_tx->r_ant_non_ht_s1	= 0x3;
+			p_cck_txrx->r_ccktx_enable	= 0xC;
+			chgTx = 1;
+			/*/ From SD3Willis suggestion !!! Set RF B as standby*/
+			/*/if (IS_HARDWARE_TYPE_8192S(pAdapter))*/
+			{
+			PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2);
+			PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2);
+			/* Disable Power save*/			
+			/*cosa r_ant_select_ofdm_val = 0x3321333;*/
+			/* 2009/01/08 MH From Sd3 Willis. We need to enable RFA/B by SW control*/
+			if (pHalData->rf_type == RF_2T2R) {
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0);
+
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0);
+				/*/PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);*/
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1);
+				PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1);
+			}
+			}			
+			pMptCtx->MptRfPath = ODM_RF_PATH_AB;
+			break;
+	default:
+				break;
+	}
+
+	
+	
+/*// r_rx_antenna_ofdm, bit0=A, bit1=B, bit2=C, bit3=D
+// r_cckrx_enable : CCK default, 0=A, 1=B, 2=C, 3=D
+// r_cckrx_enable_2 : CCK option, 0=A, 1=B, 2=C, 3=D	*/
+	switch (ulAntennaRx) {
+	case ANTENNA_A:
+		r_rx_antenna_ofdm		= 0x1;	/* A*/
+		p_cck_txrx->r_cckrx_enable	= 0x0;	/* default: A*/
+		p_cck_txrx->r_cckrx_enable_2	= 0x0;	/* option: A*/
+		chgRx = 1;
+		break;
+	case ANTENNA_B:
+		r_rx_antenna_ofdm			= 0x2;	/*/ B*/
+		p_cck_txrx->r_cckrx_enable	= 0x1;	/*/ default: B*/
+		p_cck_txrx->r_cckrx_enable_2	= 0x1;	/*/ option: B*/
+		chgRx = 1;
+		break;
+	case ANTENNA_AB:/*/ For 8192S and 8192E/U...*/
+		r_rx_antenna_ofdm		= 0x3;/*/ AB*/
+		p_cck_txrx->r_cckrx_enable	= 0x0;/*/ default:A*/
+		p_cck_txrx->r_cckrx_enable_2	= 0x1;/*/ option:B*/
+		chgRx = 1;
+		break;
+	default:
+		break;
+	}
+
+
+	if (chgTx && chgRx) {
+		switch (pHalData->rf_chip) {
+		case RF_8225:
+		case RF_8256:
+		case RF_6052:
+				/*/r_ant_sel_cck_val = r_ant_select_cck_val;*/
+				PHY_SetBBReg(pAdapter, rFPGA1_TxInfo, 0x7fffffff, r_ant_select_ofdm_val);		/*/OFDM Tx*/
+				PHY_SetBBReg(pAdapter, rFPGA0_TxInfo, 0x0000000f, r_ofdm_tx_en_val);		/*/OFDM Tx*/
+				PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm);	/*/OFDM Rx*/
+				PHY_SetBBReg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm);	/*/OFDM Rx*/
+				if (IS_HARDWARE_TYPE_8192E(pAdapter)) {
+					PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, 0x000000F0, r_rx_antenna_ofdm);	/*/OFDM Rx*/
+					PHY_SetBBReg(pAdapter, rOFDM1_TRxPathEnable, 0x000000F0, r_rx_antenna_ofdm);	/*/OFDM Rx*/
+				}
+				PHY_SetBBReg(pAdapter, rCCK0_AFESetting, bMaskByte3, r_ant_select_cck_val);/*/r_ant_sel_cck_val); /CCK TxRx*/
+				break;
+
+		default:
+				DBG_871X("Unsupported RFChipID for switching antenna.\n");
+				break;
+		}
+	}
+}	/* MPT_ProSetRFPath */
+
+
+void hal_mpt_SetAntenna(PADAPTER	pAdapter)
+
+{
+	DBG_871X("Do %s\n", __func__);
+#ifdef	CONFIG_RTL8814A
+	if (IS_HARDWARE_TYPE_8814A(pAdapter)) {
+		mpt_SetRFPath_8814A(pAdapter);
+		return;
+	}
+#endif
+#if	defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
+	if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) {
+		mpt_SetRFPath_8812A(pAdapter);
+		return;
+	}
+#endif
+#ifdef	CONFIG_RTL8723B
+	if (IS_HARDWARE_TYPE_8723B(pAdapter)) {
+		mpt_SetRFPath_8723B(pAdapter);
+		return;
+	}	
+#endif	
+#ifdef	CONFIG_RTL8703B
+	if (IS_HARDWARE_TYPE_8703B(pAdapter)) {
+		mpt_SetRFPath_8703B(pAdapter);
+		return;
+	}	
+#endif	
+
+/*	else if (IS_HARDWARE_TYPE_8821B(pAdapter))
+		mpt_SetRFPath_8821B(pAdapter);
+	Prepare for 8822B
+	else if (IS_HARDWARE_TYPE_8822B(Context))
+		mpt_SetRFPath_8822B(Context);
+*/	
+	mpt_SetRFPath_819X(pAdapter);
+	DBG_871X("mpt_SetRFPath_819X Do %s\n", __func__);
+
+}
+
+
+s32 hal_mpt_SetThermalMeter(PADAPTER pAdapter, u8 target_ther)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+	if (!netif_running(pAdapter->pnetdev)) {
+		RT_TRACE(_module_mp_, _drv_warning_, ("SetThermalMeter! Fail: interface not opened!\n"));
+		return _FAIL;
+	}
+
+
+	if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == _FALSE) {
+		RT_TRACE(_module_mp_, _drv_warning_, ("SetThermalMeter: Fail! not in MP mode!\n"));
+		return _FAIL;
+	}
+
+
+	target_ther &= 0xff;
+	if (target_ther < 0x07)
+		target_ther = 0x07;
+	else if (target_ther > 0x1d)
+		target_ther = 0x1d;
+
+	pHalData->EEPROMThermalMeter = target_ther;
+
+	return _SUCCESS;
+}
+
+
+void hal_mpt_TriggerRFThermalMeter(PADAPTER pAdapter)
+{
+	PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x42, BIT17 | BIT16, 0x03);
+
+}
+
+
+u8 hal_mpt_ReadRFThermalMeter(PADAPTER pAdapter)
+
+{
+	u32 ThermalValue = 0;
+
+	ThermalValue = (u1Byte)PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, 0x42, 0xfc00);	/*0x42: RF Reg[15:10]*/
+	return (u8)ThermalValue;
+
+}
+
+
+void hal_mpt_GetThermalMeter(PADAPTER pAdapter, u8 *value)
+{
+#if 0
+	fw_cmd(pAdapter, IOCMD_GET_THERMAL_METER);
+	rtw_msleep_os(1000);
+	fw_cmd_data(pAdapter, value, 1);
+	*value &= 0xFF;
+#else
+	hal_mpt_TriggerRFThermalMeter(pAdapter);
+	rtw_msleep_os(1000);
+	*value = hal_mpt_ReadRFThermalMeter(pAdapter);
+#endif
+
+}
+
+
+void hal_mpt_SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+	
+	pAdapter->mppriv.MptCtx.bSingleCarrier = bStart;
+	
+	if (bStart) {/*/ Start Single Carrier.*/
+		RT_TRACE(_module_mp_, _drv_alert_, ("SetSingleCarrierTx: test start\n"));
+		/*/ Start Single Carrier.*/
+		/*/ 1. if OFDM block on?*/
+		if (!PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn))
+			PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 1); /*set OFDM block on*/
+
+		/*/ 2. set CCK test mode off, set to CCK normal mode*/
+		PHY_SetBBReg(pAdapter, rCCK0_System, bCCKBBMode, 0);
+
+		/*/ 3. turn on scramble setting*/
+		PHY_SetBBReg(pAdapter, rCCK0_System, bCCKScramble, 1);
+
+		/*/ 4. Turn On Continue Tx and turn off the other test modes.*/
+#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) ||  defined(CONFIG_RTL8814A)
+		if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/)
+			PHY_SetBBReg(pAdapter, rSingleTone_ContTx_Jaguar, BIT18|BIT17|BIT16, OFDM_SingleCarrier);
+		else
+#endif		
+			PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_SingleCarrier);
+
+	} else {
+		/*/ Stop Single Carrier.*/
+		/*/ Stop Single Carrier.*/
+		/*/ Turn off all test modes.*/
+#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) ||  defined(CONFIG_RTL8814A)		
+		if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/)
+			PHY_SetBBReg(pAdapter, rSingleTone_ContTx_Jaguar, BIT18|BIT17|BIT16, OFDM_ALL_OFF);
+		else
+#endif
+		
+			PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF);
+
+		rtw_msleep_os(10);
+		/*/BB Reset*/
+	    PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+	    PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+	}
+}
+
+
+void hal_mpt_SetSingleToneTx(PADAPTER pAdapter, u8 bStart)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	PMPT_CONTEXT		pMptCtx = &(pAdapter->mppriv.MptCtx);
+	u4Byte			ulAntennaTx = pHalData->AntennaTxPath;
+	static u4Byte		regRF = 0, regBB0 = 0, regBB1 = 0, regBB2 = 0, regBB3 = 0;
+	u8 rfPath;
+
+	switch (ulAntennaTx) {
+	case ANTENNA_B:
+			rfPath = ODM_RF_PATH_B;
+			break;
+	case ANTENNA_C:
+			rfPath = ODM_RF_PATH_C;
+			break;
+	case ANTENNA_D:
+			rfPath = ODM_RF_PATH_D;
+			break;
+	case ANTENNA_A:
+	default:	
+			rfPath = ODM_RF_PATH_A;
+			break;
+	}
+
+	pAdapter->mppriv.MptCtx.bSingleTone = bStart;
+	if (bStart) {
+		/*/ Start Single Tone.*/
+		/*/ <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu)*/
+		if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+			regRF = PHY_QueryRFReg(pAdapter, rfPath, LNA_Low_Gain_3, bRFRegOffsetMask);
+			
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO enabled*/	
+			PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x0);
+			PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x0);
+		} else if (IS_HARDWARE_TYPE_8192E(pAdapter)) { /*/ USB need to do RF LO disable first, PCIE isn't required to follow this order.*/
+						/*/Set MAC REG 88C: Prevent SingleTone Fail*/
+			PHY_SetMacReg(pAdapter, 0x88C, 0xF00000, 0xF);
+			PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO disabled*/
+			PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC, 0xF0000, 0x2); /*/ Tx mode*/
+		} else if (IS_HARDWARE_TYPE_8723B(pAdapter)) {
+			if (pMptCtx->MptRfPath == ODM_RF_PATH_A) {
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x2); /*/ Tx mode*/
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x56, 0xF, 0x1); /*/ RF LO enabled*/
+			} else { 
+				/*/ S0/S1 both use PATH A to configure*/
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x2); /*/ Tx mode*/
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x76, 0xF, 0x1); /*/ RF LO enabled*/
+			}
+		} else if (IS_HARDWARE_TYPE_8703B(pAdapter)) {
+			if (pMptCtx->MptRfPath == ODM_RF_PATH_A) {
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x2); /* Tx mode */
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x53, 0xF000, 0x1); /* RF LO enabled */
+			}
+		} else if (IS_HARDWARE_TYPE_8188F(pAdapter)) {
+			/*Set BB REG 88C: Prevent SingleTone Fail*/
+			PHY_SetBBReg(pAdapter, rFPGA0_AnalogParameter4, 0xF00000, 0xF);
+			PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x1);
+			PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC, 0xF0000, 0x2);
+
+		} else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) {
+#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
+			u1Byte p = ODM_RF_PATH_A;
+			
+			regRF = PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, bRFRegOffsetMask);
+			regBB0 = PHY_QueryBBReg(pAdapter, rA_RFE_Pinmux_Jaguar, bMaskDWord);
+			regBB1 = PHY_QueryBBReg(pAdapter, rB_RFE_Pinmux_Jaguar, bMaskDWord);
+			regBB2 = PHY_QueryBBReg(pAdapter, rA_RFE_Pinmux_Jaguar+4, bMaskDWord);
+			regBB3 = PHY_QueryBBReg(pAdapter, rB_RFE_Pinmux_Jaguar+4, bMaskDWord);
+			
+			PHY_SetBBReg(pAdapter, rOFDMCCKEN_Jaguar, BIT29|BIT28, 0x0); /*/ Disable CCK and OFDM*/
+			
+			if (pMptCtx->MptRfPath == ODM_RF_PATH_AB) {
+				for (p = ODM_RF_PATH_A; p <= ODM_RF_PATH_B; ++p) {					
+					PHY_SetRFReg(pAdapter, p, RF_AC_Jaguar, 0xF0000, 0x2); /*/ Tx mode: RF0x00[19:16]=4'b0010 */
+					PHY_SetRFReg(pAdapter, p, RF_AC_Jaguar, 0x1F, 0x0); /*/ Lowest RF gain index: RF_0x0[4:0] = 0*/
+					PHY_SetRFReg(pAdapter, p, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO enabled*/
+				}
+			} else {
+				PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC_Jaguar, 0xF0000, 0x2); /*/ Tx mode: RF0x00[19:16]=4'b0010 */
+				PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC_Jaguar, 0x1F, 0x0); /*/ Lowest RF gain index: RF_0x0[4:0] = 0*/
+				PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO enabled*/
+			}			
+			
+			PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar, 0xFF00F0, 0x77007);  /*/ 0xCB0[[23:16, 7:4] = 0x77007*/
+			PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar, 0xFF00F0, 0x77007);  /*/ 0xCB0[[23:16, 7:4] = 0x77007*/
+			
+			if (pHalData->ExternalPA_5G) {
+				PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar+4, 0xFF00000, 0x12); /*/ 0xCB4[23:16] = 0x12*/
+				PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar+4, 0xFF00000, 0x12); /*/ 0xEB4[23:16] = 0x12*/
+			} else if (pHalData->ExternalPA_2G) {
+				PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar+4, 0xFF00000, 0x11); /*/ 0xCB4[23:16] = 0x11*/
+				PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar+4, 0xFF00000, 0x11); /*/ 0xEB4[23:16] = 0x11*/
+			}
+#endif
+		}
+#ifdef CONFIG_RTL8814A 
+		else if (IS_HARDWARE_TYPE_8814A(pAdapter))
+			mpt_SetSingleTone_8814A(pAdapter, TRUE, FALSE);
+#endif
+		else	/*/ Turn On SingleTone and turn off the other test modes.*/
+			PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_SingleTone);			
+
+		write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
+		write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
+
+	} else {/*/ Stop Single Ton e.*/
+
+		if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+			PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask, regRF);
+			PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x1);
+			PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
+		} else if (IS_HARDWARE_TYPE_8192E(pAdapter)) {
+			PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC, 0xF0000, 0x3);/*/ Tx mode*/
+			PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x0);/*/ RF LO disabled */
+			/*/ RESTORE MAC REG 88C: Enable RF Functions*/
+			PHY_SetMacReg(pAdapter, 0x88C, 0xF00000, 0x0);
+		} else if (IS_HARDWARE_TYPE_8723B(pAdapter)) {
+			if (pMptCtx->MptRfPath == ODM_RF_PATH_A) {
+			
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x3); /*/ Rx mode*/
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x56, 0xF, 0x0); /*/ RF LO disabled*/
+			} else {
+				/*/ S0/S1 both use PATH A to configure*/
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x3); /*/ Rx mode*/
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x76, 0xF, 0x0); /*/ RF LO disabled*/
+				}
+		} else if (IS_HARDWARE_TYPE_8703B(pAdapter)) {
+		
+			if (pMptCtx->MptRfPath == ODM_RF_PATH_A) {
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x3); /* Rx mode */
+				PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x53, 0xF000, 0x0); /* RF LO disabled */
+			}
+		} else if (IS_HARDWARE_TYPE_8188F(pAdapter)) {
+			PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC, 0xF0000, 0x3); /*Tx mode*/
+			PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x0); /*RF LO disabled*/
+			/*Set BB REG 88C: Prevent SingleTone Fail*/
+			PHY_SetBBReg(pAdapter, rFPGA0_AnalogParameter4, 0xF00000, 0xc);	
+		} else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) {
+#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
+			u1Byte p = ODM_RF_PATH_A;
+			
+			PHY_SetBBReg(pAdapter, rOFDMCCKEN_Jaguar, BIT29|BIT28, 0x3); /*/ Disable CCK and OFDM*/
+
+			if (pMptCtx->MptRfPath == ODM_RF_PATH_AB) {
+				for (p = ODM_RF_PATH_A; p <= ODM_RF_PATH_B; ++p) {					
+					PHY_SetRFReg(pAdapter, p, RF_AC_Jaguar, bRFRegOffsetMask, regRF);
+					PHY_SetRFReg(pAdapter, p, LNA_Low_Gain_3, BIT1, 0x0); /*/ RF LO disabled*/
+				}
+			} else {
+				PHY_SetRFReg(pAdapter, p, RF_AC_Jaguar, bRFRegOffsetMask, regRF);
+				PHY_SetRFReg(pAdapter, p, LNA_Low_Gain_3, BIT1, 0x0); /*/ RF LO disabled*/
+			}
+			
+			PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar, bMaskDWord, regBB0); 
+			PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar, bMaskDWord, regBB1); 
+			PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar+4, bMaskDWord, regBB2);
+			PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar+4, bMaskDWord, regBB3);
+#endif
+		}
+#ifdef CONFIG_RTL8814A		
+		else if (IS_HARDWARE_TYPE_8814A(pAdapter))
+			mpt_SetSingleTone_8814A(pAdapter, FALSE, FALSE);
+
+		 else/*/ Turn off all test modes.*/			
+			PHY_SetBBReg(pAdapter, rSingleTone_ContTx_Jaguar, BIT18|BIT17|BIT16, OFDM_ALL_OFF);				   
+#endif
+		write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
+		write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
+
+	}
+}
+
+
+void hal_mpt_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart)
+{
+	pAdapter->mppriv.MptCtx.bCarrierSuppression = bStart;
+	if (bStart) {/* Start Carrier Suppression.*/
+		RT_TRACE(_module_mp_, _drv_alert_, ("SetCarrierSuppressionTx: test start\n"));
+		if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) {
+			/*/ 1. if CCK block on?*/
+			if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn))
+				write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/*set CCK block on*/
+
+			/*/Turn Off All Test Mode*/
+			if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/)
+				PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ALL_OFF);/* rSingleTone_ContTx_Jaguar*/
+			else
+				PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF);
+
+			write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2);    /*/transmit mode*/
+			write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x0);  /*/turn off scramble setting*/
+
+			/*/Set CCK Tx Test Rate*/
+			write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, 0x0);    /*/Set FTxRate to 1Mbps*/
+		}
+
+		 /*Set for dynamic set Power index*/
+		 write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
+		 write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
+
+	} else {/* Stop Carrier Suppression.*/	
+		RT_TRACE(_module_mp_, _drv_alert_, ("SetCarrierSuppressionTx: test stop\n"));
+
+		if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) {
+			write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0);    /*normal mode*/
+			write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x1);  /*turn on scramble setting*/
+
+			/*BB Reset*/
+			write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+			write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+		}
+		/*Stop for dynamic set Power index*/
+		write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
+		write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
+	}
+	DBG_871X("\n MPT_ProSetCarrierSupp() is finished.\n");
+}
+
+void hal_mpt_SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart)
+{
+	u32 cckrate;
+
+	if (bStart) {
+		RT_TRACE(_module_mp_, _drv_alert_,
+			 ("SetCCKContinuousTx: test start\n"));
+
+		/*/ 1. if CCK block on?*/
+		if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn))
+			write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/*set CCK block on*/
+
+		/*/Turn Off All Test Mode*/
+		if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(pAdapter))
+			PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ALL_OFF);/*rSingleTone_ContTx_Jaguar*/
+		else
+			PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF);
+
+		/*/Set CCK Tx Test Rate*/
+
+		cckrate  = pAdapter->mppriv.rateidx;
+
+		write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, cckrate);
+		write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2);	/*/transmit mode*/
+		write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable);	/*/turn on scramble setting*/
+
+		if (!IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(pAdapter)) {
+			PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x3);  /* rCCK0_RxHP 0xa15[1:0] = 11 force cck rxiq = 0*/
+			PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1);		/*/ 0xc08[16] = 1 force ofdm rxiq = ofdm txiq*/
+			PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, BIT14, 1);
+			PHY_SetBBReg(pAdapter, 0x0B34, BIT14, 1);
+		}
+
+		write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
+		write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
+
+	} else {
+		RT_TRACE(_module_mp_, _drv_info_,
+			 ("SetCCKContinuousTx: test stop\n"));
+
+		write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0);	/*/normal mode*/
+		write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable);	/*/turn on scramble setting*/
+
+		if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter)  && !IS_HARDWARE_TYPE_8814A(pAdapter) /* && !IS_HARDWARE_TYPE_8822B(pAdapter) */) {
+			PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x0);/* rCCK0_RxHP 0xa15[1:0] = 2b00*/
+			PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x0);		/*/ 0xc08[16] = 0*/
+			
+			PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, BIT14, 0);
+			PHY_SetBBReg(pAdapter, 0x0B34, BIT14, 0);
+		}
+		
+		/*/BB Reset*/
+		write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+		write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+
+		write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
+		write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
+	}
+
+	pAdapter->mppriv.MptCtx.bCckContTx = bStart;
+	pAdapter->mppriv.MptCtx.bOfdmContTx = _FALSE;
+}
+
+void hal_mpt_SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+	if (bStart) {
+		RT_TRACE(_module_mp_, _drv_info_, ("SetOFDMContinuousTx: test start\n"));/*/ 1. if OFDM block on?*/
+		if (!PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn))
+			PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 1);/*/set OFDM block on*/
+
+		/*/ 2. set CCK test mode off, set to CCK normal mode*/
+		PHY_SetBBReg(pAdapter, rCCK0_System, bCCKBBMode, 0);
+
+		/*/ 3. turn on scramble setting*/
+		PHY_SetBBReg(pAdapter, rCCK0_System, bCCKScramble, 1);
+
+		if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter) && !IS_HARDWARE_TYPE_8814A(pAdapter) /*&& !IS_HARDWARE_TYPE_8822B(pAdapter)*/) {
+			PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x3);			/* rCCK0_RxHP 0xa15[1:0] = 2b'11*/
+			PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1);		/* 0xc08[16] = 1*/
+		}
+
+		/*/ 4. Turn On Continue Tx and turn off the other test modes.*/
+		if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/)
+			PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ContinuousTx);/*rSingleTone_ContTx_Jaguar*/
+		else
+			PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ContinuousTx);
+
+		write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
+		write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
+
+	} else {
+		RT_TRACE(_module_mp_, _drv_info_, ("SetOFDMContinuousTx: test stop\n"));
+		if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/)
+			PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ALL_OFF);
+		else
+			PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF);
+		/*/Delay 10 ms*/
+		rtw_msleep_os(10);
+		
+		if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter) && !IS_HARDWARE_TYPE_8814A(pAdapter) /*&&! IS_HARDWARE_TYPE_8822B(pAdapter)*/) {
+			PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x0);/*/ 0xa15[1:0] = 0*/
+			PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x0);/*/ 0xc08[16] = 0*/
+		}
+		
+		/*/BB Reset*/
+		PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+		PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+
+		write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
+		write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
+	}
+
+	pAdapter->mppriv.MptCtx.bCckContTx = _FALSE;
+	pAdapter->mppriv.MptCtx.bOfdmContTx = bStart;
+}
+
+void hal_mpt_SetContinuousTx(PADAPTER pAdapter, u8 bStart)
+{
+	RT_TRACE(_module_mp_, _drv_info_,
+		 ("SetContinuousTx: rate:%d\n", pAdapter->mppriv.rateidx));
+
+	pAdapter->mppriv.MptCtx.bStartContTx = bStart;
+
+	if (pAdapter->mppriv.rateidx <= MPT_RATE_11M)
+		hal_mpt_SetCCKContinuousTx(pAdapter, bStart);
+	else if (pAdapter->mppriv.rateidx >= MPT_RATE_6M) 
+		hal_mpt_SetOFDMContinuousTx(pAdapter, bStart);
+}
+
+#endif /* CONFIG_MP_INCLUDE*/
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/hal_phy.c b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_phy.c
new file mode 100644
index 000000000..feb619edb
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/hal_phy.c
@@ -0,0 +1,285 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#define _HAL_PHY_C_
+
+#include <drv_types.h>
+
+//================================================================================
+//	Constant.
+//================================================================================
+// 2008/11/20 MH For Debug only, RF
+static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG];
+
+/**
+* Function:	PHY_CalculateBitShift
+*
+* OverView:	Get shifted position of the BitMask
+*
+* Input:
+*			u4Byte		BitMask,	
+*
+* Output:	none
+* Return:		u4Byte		Return the shift bit bit position of the mask
+*/
+u32
+PHY_CalculateBitShift(
+	u32 BitMask
+	)
+{
+	u32 i;
+
+	for(i=0; i<=31; i++)
+	{
+		if ( ((BitMask>>i) &  0x1 ) == 1)
+			break;
+	}
+
+	return (i);
+}
+
+
+//
+// ==> RF shadow Operation API Code Section!!!
+//
+/*-----------------------------------------------------------------------------
+ * Function:	PHY_RFShadowRead
+ *				PHY_RFShadowWrite
+ *				PHY_RFShadowCompare
+ *				PHY_RFShadowRecorver
+ *				PHY_RFShadowCompareAll
+ *				PHY_RFShadowRecorverAll
+ *				PHY_RFShadowCompareFlagSet
+ *				PHY_RFShadowRecorverFlagSet
+ *
+ * Overview:	When we set RF register, we must write shadow at first.
+ *			When we are running, we must compare shadow abd locate error addr.
+ *			Decide to recorver or not.
+ *
+ * Input:       NONE
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ * When			Who		Remark
+ * 11/20/2008 	MHC		Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+u32
+PHY_RFShadowRead(
+	IN	PADAPTER		Adapter,
+	IN	u8				eRFPath,
+	IN	u32				Offset)
+{
+	return	RF_Shadow[eRFPath][Offset].Value;
+
+}	/* PHY_RFShadowRead */
+
+
+VOID
+PHY_RFShadowWrite(
+	IN	PADAPTER		Adapter,
+	IN	u8				eRFPath,
+	IN	u32				Offset,
+	IN	u32				Data)
+{
+	RF_Shadow[eRFPath][Offset].Value = (Data & bRFRegOffsetMask);
+	RF_Shadow[eRFPath][Offset].Driver_Write = _TRUE;
+
+}	/* PHY_RFShadowWrite */
+
+
+BOOLEAN
+PHY_RFShadowCompare(
+	IN	PADAPTER		Adapter,
+	IN	u8				eRFPath,
+	IN	u32				Offset)
+{
+	u32	reg;
+	// Check if we need to check the register
+	if (RF_Shadow[eRFPath][Offset].Compare == _TRUE)
+	{
+		reg = rtw_hal_read_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask);
+		// Compare shadow and real rf register for 20bits!!
+		if (RF_Shadow[eRFPath][Offset].Value != reg)
+		{
+			// Locate error position.
+			RF_Shadow[eRFPath][Offset].ErrorOrNot = _TRUE;
+			//RT_TRACE(COMP_INIT, DBG_LOUD,
+			//("PHY_RFShadowCompare RF-%d Addr%02lx Err = %05lx\n",
+			//eRFPath, Offset, reg));
+		}
+		return RF_Shadow[eRFPath][Offset].ErrorOrNot ;
+	}
+	return _FALSE;
+}	/* PHY_RFShadowCompare */
+
+
+VOID
+PHY_RFShadowRecorver(
+	IN	PADAPTER		Adapter,
+	IN	u8				eRFPath,
+	IN	u32				Offset)
+{
+	// Check if the address is error
+	if (RF_Shadow[eRFPath][Offset].ErrorOrNot == _TRUE)
+	{
+		// Check if we need to recorver the register.
+		if (RF_Shadow[eRFPath][Offset].Recorver == _TRUE)
+		{
+			rtw_hal_write_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask,
+							RF_Shadow[eRFPath][Offset].Value);
+			//RT_TRACE(COMP_INIT, DBG_LOUD,
+			//("PHY_RFShadowRecorver RF-%d Addr%02lx=%05lx",
+			//eRFPath, Offset, RF_Shadow[eRFPath][Offset].Value));
+		}
+	}
+
+}	/* PHY_RFShadowRecorver */
+
+
+VOID
+PHY_RFShadowCompareAll(
+	IN	PADAPTER			Adapter)
+{
+	u8		eRFPath = 0 ;
+	u32		Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter);
+
+	for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
+	{
+		for (Offset = 0; Offset < maxReg; Offset++)
+		{
+			PHY_RFShadowCompare(Adapter, eRFPath, Offset);
+		}
+	}
+
+}	/* PHY_RFShadowCompareAll */
+
+
+VOID
+PHY_RFShadowRecorverAll(
+	IN	PADAPTER			Adapter)
+{
+	u8		eRFPath =0;
+	u32		Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter);
+
+	for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
+	{
+		for (Offset = 0; Offset < maxReg; Offset++)
+		{
+			PHY_RFShadowRecorver(Adapter, eRFPath, Offset);
+		}
+	}
+
+}	/* PHY_RFShadowRecorverAll */
+
+
+VOID
+PHY_RFShadowCompareFlagSet(
+	IN	PADAPTER		Adapter,
+	IN	u8				eRFPath,
+	IN	u32				Offset,
+	IN	u8				Type)
+{
+	// Set True or False!!!
+	RF_Shadow[eRFPath][Offset].Compare = Type;
+
+}	/* PHY_RFShadowCompareFlagSet */
+
+
+VOID
+PHY_RFShadowRecorverFlagSet(
+	IN	PADAPTER		Adapter,
+	IN	u8				eRFPath,
+	IN	u32				Offset,
+	IN	u8				Type)
+{
+	// Set True or False!!!
+	RF_Shadow[eRFPath][Offset].Recorver= Type;
+
+}	/* PHY_RFShadowRecorverFlagSet */
+
+
+VOID
+PHY_RFShadowCompareFlagSetAll(
+	IN	PADAPTER			Adapter)
+{
+	u8		eRFPath = 0;
+	u32		Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter);
+
+	for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
+	{
+		for (Offset = 0; Offset < maxReg; Offset++)
+		{
+			// 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!!
+			if (Offset != 0x26 && Offset != 0x27)
+				PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, _FALSE);
+			else
+				PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, _TRUE);
+		}
+	}
+
+}	/* PHY_RFShadowCompareFlagSetAll */
+
+
+VOID
+PHY_RFShadowRecorverFlagSetAll(
+	IN	PADAPTER			Adapter)
+{
+	u8		eRFPath = 0;
+	u32		Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter);
+
+	for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
+	{
+		for (Offset = 0; Offset < maxReg; Offset++)
+		{
+			// 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!!
+			if (Offset != 0x26 && Offset != 0x27)
+				PHY_RFShadowRecorverFlagSet(Adapter, eRFPath, Offset, _FALSE);
+			else
+				PHY_RFShadowRecorverFlagSet(Adapter, eRFPath, Offset, _TRUE);
+		}
+	}
+
+}	/* PHY_RFShadowCompareFlagSetAll */
+
+VOID
+PHY_RFShadowRefresh(
+	IN	PADAPTER			Adapter)
+{
+	u8		eRFPath = 0;
+	u32		Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter);
+
+	for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
+	{
+		for (Offset = 0; Offset < maxReg; Offset++)
+		{
+			RF_Shadow[eRFPath][Offset].Value = 0;
+			RF_Shadow[eRFPath][Offset].Compare = _FALSE;
+			RF_Shadow[eRFPath][Offset].Recorver  = _FALSE;
+			RF_Shadow[eRFPath][Offset].ErrorOrNot = _FALSE;
+			RF_Shadow[eRFPath][Offset].Driver_Write = _FALSE;
+		}
+	}
+
+}	/* PHY_RFShadowRead */
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/led/hal_sdio_led.c b/drivers/net/wireless/realtek/rtl8723cs/hal/led/hal_sdio_led.c
new file mode 100644
index 000000000..d987fc1d0
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/led/hal_sdio_led.c
@@ -0,0 +1,2420 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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 <drv_types.h>
+#include <hal_data.h>
+
+//
+//	Description:
+//		Implementation of LED blinking behavior.
+//		It toggle off LED and schedule corresponding timer if necessary.
+//
+void
+SwLedBlink(
+	PLED_SDIO			pLed
+	)
+{
+	_adapter			*padapter = pLed->padapter;
+	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	u8				bStopBlinking = _FALSE;
+
+	// Change LED according to BlinkingLedState specified.
+	if( pLed->BlinkingLedState == RTW_LED_ON )
+	{
+		SwLedOn(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+	}
+	else
+	{
+		SwLedOff(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+	}
+
+	// Determine if we shall change LED state again.
+	pLed->BlinkTimes--;
+	switch(pLed->CurrLedState)
+	{
+
+	case LED_BLINK_NORMAL:
+		if(pLed->BlinkTimes == 0)
+		{
+			bStopBlinking = _TRUE;
+		}
+		break;
+
+	case LED_BLINK_StartToBlink:
+		if( check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE) )
+		{
+			bStopBlinking = _TRUE;
+		}
+		if( check_fwstate(pmlmepriv, _FW_LINKED) &&
+			(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) )
+		{
+			bStopBlinking = _TRUE;
+		}
+		else if(pLed->BlinkTimes == 0)
+		{
+			bStopBlinking = _TRUE;
+		}
+		break;
+
+	case LED_BLINK_WPS:
+		if( pLed->BlinkTimes == 0 )
+		{
+			bStopBlinking = _TRUE;
+		}
+		break;
+
+
+	default:
+		bStopBlinking = _TRUE;
+		break;
+
+	}
+
+	if(bStopBlinking)
+	{
+		if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+		{
+			SwLedOff(padapter, pLed);
+		}
+		else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (pLed->bLedOn == _FALSE))
+		{
+			SwLedOn(padapter, pLed);
+		}
+		else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) &&  pLed->bLedOn == _TRUE)
+		{
+			SwLedOff(padapter, pLed);
+		}
+
+		pLed->BlinkTimes = 0;
+		pLed->bLedBlinkInProgress = _FALSE;
+	}
+	else
+	{
+		// Assign LED state to toggle.
+		if( pLed->BlinkingLedState == RTW_LED_ON )
+			pLed->BlinkingLedState = RTW_LED_OFF;
+		else
+			pLed->BlinkingLedState = RTW_LED_ON;
+
+		// Schedule a timer to toggle LED state.
+		switch( pLed->CurrLedState )
+		{
+		case LED_BLINK_NORMAL:
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+			break;
+
+		case LED_BLINK_SLOWLY:
+		case LED_BLINK_StartToBlink:
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+			break;
+
+		case LED_BLINK_WPS:
+			{
+				if( pLed->BlinkingLedState == RTW_LED_ON )
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+				else
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+			}
+			break;
+
+		default:
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+			break;
+		}
+	}
+}
+
+void
+SwLedBlink1(
+	PLED_SDIO			pLed
+	)
+{
+	_adapter				*padapter = pLed->padapter;
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(padapter);	
+	struct led_priv		*ledpriv = &(padapter->ledpriv);
+	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
+	PLED_SDIO 			pLed1 = &(ledpriv->SwLed1);
+	u8					bStopBlinking = _FALSE;
+	
+	if(pHalData->CustomerID == RT_CID_819x_CAMEO)
+		pLed = &(ledpriv->SwLed1);
+
+	// Change LED according to BlinkingLedState specified.
+	if( pLed->BlinkingLedState == RTW_LED_ON )
+	{
+		SwLedOn(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+	}
+	else
+	{
+		SwLedOff(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+	}
+
+
+	if(pHalData->CustomerID == RT_CID_DEFAULT)
+	{
+		if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+		{
+			if(!pLed1->bSWLedCtrl)
+			{
+				SwLedOn(padapter, pLed1);
+				pLed1->bSWLedCtrl = _TRUE;
+			}
+			else if(!pLed1->bLedOn)
+				SwLedOn(padapter, pLed1);
+			RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn on pLed1\n"));
+		}
+		else
+		{
+			if(!pLed1->bSWLedCtrl)
+			{
+				SwLedOff(padapter, pLed1);
+				pLed1->bSWLedCtrl = _TRUE;
+			}
+			else if(pLed1->bLedOn)
+				SwLedOff(padapter, pLed1);
+			RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn off pLed1\n"));
+		}
+	}
+
+	switch(pLed->CurrLedState)
+	{
+		case LED_BLINK_SLOWLY:
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+			break;
+
+		case LED_BLINK_NORMAL:
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+			break;
+
+		case LED_BLINK_SCAN:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+				{
+					pLed->bLedLinkBlinkInProgress = _TRUE;
+					pLed->CurrLedState = LED_BLINK_NORMAL;
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+				{
+					pLed->bLedNoLinkBlinkInProgress = _TRUE;
+					pLed->CurrLedState = LED_BLINK_SLOWLY;
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		case LED_BLINK_TXRX:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+				{
+					pLed->bLedLinkBlinkInProgress = _TRUE;
+					pLed->CurrLedState = LED_BLINK_NORMAL;
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+				{
+					pLed->bLedNoLinkBlinkInProgress = _TRUE;
+					pLed->CurrLedState = LED_BLINK_SLOWLY;
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				pLed->BlinkTimes = 0;
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		case LED_BLINK_WPS:
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+			break;
+
+		case LED_BLINK_WPS_STOP:	//WPS success
+			if(pLed->BlinkingLedState == RTW_LED_ON)
+			{
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+				bStopBlinking = _FALSE;
+			}
+			else
+			{
+				bStopBlinking = _TRUE;
+			}
+
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					pLed->bLedLinkBlinkInProgress = _TRUE;
+					pLed->CurrLedState = LED_BLINK_NORMAL;
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+			break;
+
+		default:
+			break;
+	}
+
+}
+
+void
+SwLedBlink2(
+	PLED_SDIO			pLed
+	)
+{
+	_adapter				*padapter = pLed->padapter;
+	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
+	u8					bStopBlinking = _FALSE;
+
+	// Change LED according to BlinkingLedState specified.
+	if( pLed->BlinkingLedState == RTW_LED_ON)
+	{
+		SwLedOn(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+	}
+	else
+	{
+		SwLedOff(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+	}
+
+	switch(pLed->CurrLedState)
+	{
+		case LED_BLINK_SCAN:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+				{
+					pLed->CurrLedState = RTW_LED_ON;
+					pLed->BlinkingLedState = RTW_LED_ON;
+					SwLedOn(padapter, pLed);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState));
+
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+				{
+					pLed->CurrLedState = RTW_LED_OFF;
+					pLed->BlinkingLedState = RTW_LED_OFF;
+					SwLedOff(padapter, pLed);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState));
+				}
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					 if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		case LED_BLINK_TXRX:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+				{
+					pLed->CurrLedState = RTW_LED_ON;
+					pLed->BlinkingLedState = RTW_LED_ON;
+					SwLedOn(padapter, pLed);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState));
+
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+				{
+					pLed->CurrLedState = RTW_LED_OFF;
+					pLed->BlinkingLedState = RTW_LED_OFF;
+					SwLedOff(padapter, pLed);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState));
+				}
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					 if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		default:
+			break;
+	}
+
+}
+
+void
+SwLedBlink3(
+	PLED_SDIO			pLed
+	)
+{
+	_adapter			*padapter = pLed->padapter;
+	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	u8				bStopBlinking = _FALSE;
+
+	// Change LED according to BlinkingLedState specified.
+	if( pLed->BlinkingLedState == RTW_LED_ON )
+	{
+		SwLedOn(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+	}
+	else
+	{
+		if(pLed->CurrLedState != LED_BLINK_WPS_STOP)
+			SwLedOff(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+	}
+
+	switch(pLed->CurrLedState)
+	{
+		case LED_BLINK_SCAN:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+				{
+					pLed->CurrLedState = RTW_LED_ON;
+					pLed->BlinkingLedState = RTW_LED_ON;
+					if( !pLed->bLedOn )
+						SwLedOn(padapter, pLed);
+
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+				{
+					pLed->CurrLedState = RTW_LED_OFF;
+					pLed->BlinkingLedState = RTW_LED_OFF;
+					if( pLed->bLedOn )
+						SwLedOff(padapter, pLed);
+
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+				 	if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		case LED_BLINK_TXRX:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+				{
+					pLed->CurrLedState = RTW_LED_ON;
+					pLed->BlinkingLedState = RTW_LED_ON;
+
+					if( !pLed->bLedOn )
+						SwLedOn(padapter, pLed);
+
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+				{
+					pLed->CurrLedState = RTW_LED_OFF;
+					pLed->BlinkingLedState = RTW_LED_OFF;
+
+					if( pLed->bLedOn )
+						SwLedOff(padapter, pLed);
+
+
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		case LED_BLINK_WPS:
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+			break;
+
+		case LED_BLINK_WPS_STOP:	//WPS success
+			if(pLed->BlinkingLedState == RTW_LED_ON)
+			{
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+				bStopBlinking = _FALSE;
+			}
+			else
+			{
+				bStopBlinking = _TRUE;
+			}
+
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					pLed->CurrLedState = RTW_LED_ON;
+					pLed->BlinkingLedState = RTW_LED_ON;
+					SwLedOn(padapter, pLed);
+					RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+				}
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+			break;
+
+
+		default:
+			break;
+	}
+
+}
+
+
+void
+SwLedBlink4(
+	PLED_SDIO			pLed
+	)
+{
+	_adapter			*padapter = pLed->padapter;
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	PLED_SDIO 		pLed1 = &(ledpriv->SwLed1);
+	u8				bStopBlinking = _FALSE;
+
+	// Change LED according to BlinkingLedState specified.
+	if( pLed->BlinkingLedState == RTW_LED_ON )
+	{
+		SwLedOn(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+	}
+	else
+	{
+		SwLedOff(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+	}
+
+	if(!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN)
+	{
+		pLed1->BlinkingLedState = RTW_LED_OFF;
+		pLed1->CurrLedState = RTW_LED_OFF;
+		SwLedOff(padapter, pLed1);
+	}
+
+	switch(pLed->CurrLedState)
+	{
+		case LED_BLINK_SLOWLY:
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+			break;
+
+		case LED_BLINK_StartToBlink:
+			if( pLed->bLedOn )
+			{
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+			}
+			else
+			{
+				pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+			}
+			break;
+
+		case LED_BLINK_SCAN:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _FALSE;
+			}
+
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+					pLed->CurrLedState = LED_BLINK_SLOWLY;
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+				}
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					 if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		case LED_BLINK_TXRX:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					pLed->bLedNoLinkBlinkInProgress = _TRUE;
+					pLed->CurrLedState = LED_BLINK_SLOWLY;
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+				}
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		case LED_BLINK_WPS:
+			if( pLed->bLedOn )
+			{
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+			}
+			else
+			{
+				pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+			}
+			break;
+
+		case LED_BLINK_WPS_STOP:	//WPS authentication fail
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+			break;
+
+		case LED_BLINK_WPS_STOP_OVERLAP:	//WPS session overlap
+			pLed->BlinkTimes--;
+			if(pLed->BlinkTimes == 0)
+			{
+				if(pLed->bLedOn)
+				{
+					pLed->BlinkTimes = 1;
+				}
+				else
+				{
+					bStopBlinking = _TRUE;
+				}
+			}
+
+			if(bStopBlinking)
+			{
+				pLed->BlinkTimes = 10;
+				pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+			}
+			else
+			{
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+			}
+			break;
+
+		default:
+			break;
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState));
+
+
+}
+
+void
+SwLedBlink5(
+	PLED_SDIO			pLed
+	)
+{
+	_adapter			*padapter = pLed->padapter;
+	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	u8				bStopBlinking = _FALSE;
+
+	// Change LED according to BlinkingLedState specified.
+	if( pLed->BlinkingLedState == RTW_LED_ON )
+	{
+		SwLedOn(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+	}
+	else
+	{
+		SwLedOff(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+	}
+
+	switch(pLed->CurrLedState)
+	{
+		case LED_BLINK_SCAN:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+				{
+					pLed->CurrLedState = RTW_LED_OFF;
+					pLed->BlinkingLedState = RTW_LED_OFF;
+					if(pLed->bLedOn)
+						SwLedOff(padapter, pLed);
+				}
+				else
+				{		pLed->CurrLedState = RTW_LED_ON;
+						pLed->BlinkingLedState = RTW_LED_ON;
+						if(!pLed->bLedOn)
+							_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+				}
+
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+
+		case LED_BLINK_TXRX:
+			pLed->BlinkTimes--;
+			if( pLed->BlinkTimes == 0 )
+			{
+				bStopBlinking = _TRUE;
+			}
+
+			if(bStopBlinking)
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+				{
+					pLed->CurrLedState = RTW_LED_OFF;
+					pLed->BlinkingLedState = RTW_LED_OFF;
+					if(pLed->bLedOn)
+						SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					pLed->CurrLedState = RTW_LED_ON;
+					pLed->BlinkingLedState = RTW_LED_ON;
+					if(!pLed->bLedOn)
+						_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+				}
+
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+				{
+					SwLedOff(padapter, pLed);
+				}
+				else
+				{
+					 if( pLed->bLedOn )
+						pLed->BlinkingLedState = RTW_LED_OFF;
+					else
+						pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+				}
+			}
+			break;
+
+		default:
+			break;
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState));
+
+
+}
+
+void
+SwLedBlink6(
+	PLED_SDIO			pLed
+	)
+{
+	_adapter			*padapter = pLed->padapter;
+	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
+	u8				bStopBlinking = _FALSE;
+
+	// Change LED according to BlinkingLedState specified.
+	if( pLed->BlinkingLedState == RTW_LED_ON )
+	{
+		SwLedOn(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+	}
+	else
+	{
+		SwLedOff(padapter, pLed);
+		RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("<==== blink6\n"));
+}
+
+//
+//	Description:
+//		Handler function of LED Blinking.
+//		We dispatch acture LED blink action according to LedStrategy.
+//
+void BlinkHandler(PLED_SDIO	pLed)
+{
+	_adapter		*padapter = pLed->padapter;
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+
+	//DBG_871X("%s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
+	if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) {
+		DBG_871X("%s bDriverStopped:%s, bSurpriseRemoved:%s\n"
+		, __func__
+		, rtw_is_drv_stopped(padapter)?"True":"False"
+		, rtw_is_surprise_removed(padapter)?"True":"False");
+		
+		return;
+	}
+
+	switch(ledpriv->LedStrategy)
+	{
+		case SW_LED_MODE0:
+			SwLedBlink(pLed);
+			break;
+		
+		case SW_LED_MODE1:
+			SwLedBlink1(pLed);
+			break;
+		
+		case SW_LED_MODE2:
+			SwLedBlink2(pLed);
+			break;
+			
+		case SW_LED_MODE3:
+			SwLedBlink3(pLed);
+			break;
+
+		case SW_LED_MODE4:
+			SwLedBlink4(pLed);
+			break;			
+
+		case SW_LED_MODE5:
+			SwLedBlink5(pLed);
+			break;
+
+		case SW_LED_MODE6:
+			SwLedBlink6(pLed);
+			break;
+
+		default:
+			//RT_TRACE(COMP_LED, DBG_LOUD, ("BlinkWorkItemCallback 0x%x \n", pHalData->LedStrategy));
+			//SwLedBlink(pLed);
+			break;
+	}
+}
+
+//
+//	Description:
+//		Callback function of LED BlinkTimer, 
+//		it just schedules to corresponding BlinkWorkItem/led_blink_hdl
+//
+void BlinkTimerCallback(struct timer_list *t)
+{
+#if 0
+	PLED_SDIO	 pLed = (PLED_SDIO)data;
+	_adapter		*padapter = pLed->padapter;
+
+	//DBG_871X("%s\n", __FUNCTION__);
+
+	if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) {
+		/*DBG_871X("%s bDriverStopped:%s, bSurpriseRemoved:%s\n"
+			, __func__
+			, rtw_is_drv_stopped(padapter)?"True":"False"
+			, rtw_is_surprise_removed(padapter)?"True":"False" );*/
+		return;
+	}
+
+	#ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
+	rtw_led_blink_cmd(padapter, pLed);
+	#else
+	_set_workitem(&(pLed->BlinkWorkItem));
+	#endif
+#endif
+}
+
+//
+//	Description:
+//		Callback function of LED BlinkWorkItem.
+//		We dispatch acture LED blink action according to LedStrategy.
+//
+void BlinkWorkItemCallback(_workitem *work)
+{
+	PLED_SDIO	 pLed = container_of(work, LED_SDIO, BlinkWorkItem);
+	BlinkHandler(pLed);
+}
+
+static void
+SwLedControlMode0(
+	_adapter		*padapter,
+	LED_CTL_MODE		LedAction
+)
+{
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+	PLED_SDIO	pLed = &(ledpriv->SwLed1);
+
+	// Decide led state
+	switch(LedAction)
+	{
+	case LED_CTL_TX:
+	case LED_CTL_RX:
+		if( pLed->bLedBlinkInProgress == _FALSE )
+		{
+			pLed->bLedBlinkInProgress = _TRUE;
+
+			pLed->CurrLedState = LED_BLINK_NORMAL;
+			pLed->BlinkTimes = 2;
+
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+		}
+		break;
+
+	case LED_CTL_START_TO_LINK:
+		if( pLed->bLedBlinkInProgress == _FALSE )
+		{
+			pLed->bLedBlinkInProgress = _TRUE;
+
+			pLed->CurrLedState = LED_BLINK_StartToBlink;
+			pLed->BlinkTimes = 24;
+
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+		}
+		else
+		{
+			pLed->CurrLedState = LED_BLINK_StartToBlink;
+		}
+		break;
+
+	case LED_CTL_LINK:
+		pLed->CurrLedState = RTW_LED_ON;
+		if( pLed->bLedBlinkInProgress == _FALSE )
+		{
+			pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), 0);
+		}
+		break;
+
+	case LED_CTL_NO_LINK:
+		pLed->CurrLedState = RTW_LED_OFF;
+		if( pLed->bLedBlinkInProgress == _FALSE )
+		{
+			pLed->BlinkingLedState = RTW_LED_OFF;
+			_set_timer(&(pLed->BlinkTimer), 0);
+		}
+		break;
+
+	case LED_CTL_POWER_OFF:
+		pLed->CurrLedState = RTW_LED_OFF;
+		if(pLed->bLedBlinkInProgress)
+		{
+			_cancel_timer_ex(&(pLed->BlinkTimer));
+			pLed->bLedBlinkInProgress = _FALSE;
+		}
+		SwLedOff(padapter, pLed);
+		break;
+
+	case LED_CTL_START_WPS:
+		if( pLed->bLedBlinkInProgress == _FALSE || pLed->CurrLedState == RTW_LED_ON)
+		{
+			pLed->bLedBlinkInProgress = _TRUE;
+
+			pLed->CurrLedState = LED_BLINK_WPS;
+			pLed->BlinkTimes = 20;
+
+			if( pLed->bLedOn )
+			{
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+			}
+			else
+			{
+				pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+			}
+		}
+		break;
+
+	case LED_CTL_STOP_WPS:
+		if(pLed->bLedBlinkInProgress)
+		{
+			pLed->CurrLedState = RTW_LED_OFF;
+			_cancel_timer_ex(&(pLed->BlinkTimer));
+			pLed->bLedBlinkInProgress = _FALSE;
+		}
+		break;
+
+
+	default:
+		break;
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
+
+}
+
+ //ALPHA, added by chiyoko, 20090106
+static void
+SwLedControlMode1(
+	_adapter		*padapter,
+	LED_CTL_MODE		LedAction
+)
+{
+	struct led_priv		*ledpriv = &(padapter->ledpriv);
+	PLED_SDIO			pLed = &(ledpriv->SwLed0);
+	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(padapter);
+	
+	if(pHalData->CustomerID == RT_CID_819x_CAMEO)
+		pLed = &(ledpriv->SwLed1);
+
+	switch(LedAction)
+	{
+		case LED_CTL_POWER_ON:
+		case LED_CTL_START_TO_LINK:
+		case LED_CTL_NO_LINK:
+			if( pLed->bLedNoLinkBlinkInProgress == _FALSE )
+			{
+				if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+				{
+					return;
+				}
+				if( pLed->bLedLinkBlinkInProgress == _TRUE )
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedLinkBlinkInProgress = _FALSE;
+				}
+	 			if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+	 			}
+
+				pLed->bLedNoLinkBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_SLOWLY;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_LINK:
+			if( pLed->bLedLinkBlinkInProgress == _FALSE )
+			{
+				if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+				{
+					return;
+				}
+				if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+				}
+				if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+	 			}
+				pLed->bLedLinkBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_NORMAL;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_SITE_SURVEY:
+			 if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+			 	;
+			 else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+			 {
+			 	if(IS_LED_WPS_BLINKING(pLed))
+					return;
+
+	  			if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+				}
+				if( pLed->bLedLinkBlinkInProgress == _TRUE )
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					 pLed->bLedLinkBlinkInProgress = _FALSE;
+				}
+	 			if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				pLed->bLedScanBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_SCAN;
+				pLed->BlinkTimes = 24;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+
+			 }
+			break;
+
+		case LED_CTL_TX:
+		case LED_CTL_RX:
+			if(pLed->bLedBlinkInProgress ==_FALSE)
+			{
+				if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+				{
+					return;
+				}
+				if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+				}
+				if( pLed->bLedLinkBlinkInProgress == _TRUE )
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedLinkBlinkInProgress = _FALSE;
+				}
+				pLed->bLedBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_TXRX;
+				pLed->BlinkTimes = 2;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_START_WPS: //wait until xinpin finish
+		case LED_CTL_START_WPS_BOTTON:
+			 if(pLed->bLedWPSBlinkInProgress ==_FALSE)
+			 {
+				if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+				}
+				if( pLed->bLedLinkBlinkInProgress == _TRUE )
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					 pLed->bLedLinkBlinkInProgress = _FALSE;
+				}
+				if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				if(pLed->bLedScanBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedScanBlinkInProgress = _FALSE;
+				}
+				pLed->bLedWPSBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_WPS;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+			 }
+			break;
+
+
+		case LED_CTL_STOP_WPS:
+			if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedNoLinkBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedLinkBlinkInProgress == _TRUE )
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				 pLed->bLedLinkBlinkInProgress = _FALSE;
+			}
+			if(pLed->bLedBlinkInProgress ==_TRUE)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			if(pLed->bLedScanBlinkInProgress ==_TRUE)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			if(pLed->bLedWPSBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+			}
+			else
+			{
+				pLed->bLedWPSBlinkInProgress = _TRUE;
+			}
+
+			pLed->CurrLedState = LED_BLINK_WPS_STOP;
+			if(pLed->bLedOn)
+			{
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+			}
+			else
+			{
+				pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), 0);
+			}
+			break;
+
+		case LED_CTL_STOP_WPS_FAIL:
+			if(pLed->bLedWPSBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+
+			pLed->bLedNoLinkBlinkInProgress = _TRUE;
+			pLed->CurrLedState = LED_BLINK_SLOWLY;
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+			break;
+
+		case LED_CTL_POWER_OFF:
+			pLed->CurrLedState = RTW_LED_OFF;
+			pLed->BlinkingLedState = RTW_LED_OFF;
+			if( pLed->bLedNoLinkBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedNoLinkBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedLinkBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedLinkBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedWPSBlinkInProgress )
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedScanBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+
+			SwLedOff(padapter, pLed);
+			break;
+
+		default:
+			break;
+
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
+}
+
+ //Arcadyan/Sitecom , added by chiyoko, 20090216
+static void
+SwLedControlMode2(
+	_adapter				*padapter,
+	LED_CTL_MODE		LedAction
+)
+{
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	PLED_SDIO 		pLed = &(ledpriv->SwLed0);
+
+	switch(LedAction)
+	{
+		case LED_CTL_SITE_SURVEY:
+			 if(pmlmepriv->LinkDetectInfo.bBusyTraffic)
+			 	;
+			 else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+			 {
+			 	if(IS_LED_WPS_BLINKING(pLed))
+					return;
+
+	 			if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				pLed->bLedScanBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_SCAN;
+				pLed->BlinkTimes = 24;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+			 }
+			break;
+
+		case LED_CTL_TX:
+		case LED_CTL_RX:
+	 		if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+	  		{
+	  		  	if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+				{
+					return;
+				}
+
+				pLed->bLedBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_TXRX;
+				pLed->BlinkTimes = 2;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_LINK:
+			pLed->CurrLedState = RTW_LED_ON;
+			pLed->BlinkingLedState = RTW_LED_ON;
+			if( pLed->bLedBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedScanBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+
+			_set_timer(&(pLed->BlinkTimer), 0);
+			break;
+
+		case LED_CTL_START_WPS: //wait until xinpin finish
+		case LED_CTL_START_WPS_BOTTON:
+			if(pLed->bLedWPSBlinkInProgress ==_FALSE)
+			{
+				if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				if(pLed->bLedScanBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedScanBlinkInProgress = _FALSE;
+				}
+				pLed->bLedWPSBlinkInProgress = _TRUE;
+				pLed->CurrLedState = RTW_LED_ON;
+				pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), 0);
+			 }
+			break;
+
+		case LED_CTL_STOP_WPS:
+			pLed->bLedWPSBlinkInProgress = _FALSE;
+			if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+			{
+				pLed->CurrLedState = RTW_LED_OFF;
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), 0);
+			}
+			else
+			{
+				pLed->CurrLedState = RTW_LED_ON;
+				pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), 0);
+				RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+			}
+			break;
+
+		case LED_CTL_STOP_WPS_FAIL:
+			pLed->bLedWPSBlinkInProgress = _FALSE;
+			pLed->CurrLedState = RTW_LED_OFF;
+			pLed->BlinkingLedState = RTW_LED_OFF;
+			_set_timer(&(pLed->BlinkTimer), 0);
+			RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+			break;
+
+		case LED_CTL_START_TO_LINK:
+		case LED_CTL_NO_LINK:
+			if(!IS_LED_BLINKING(pLed))
+			{
+				pLed->CurrLedState = RTW_LED_OFF;
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), 0);
+			}
+			break;
+
+		case LED_CTL_POWER_OFF:
+			pLed->CurrLedState = RTW_LED_OFF;
+			pLed->BlinkingLedState = RTW_LED_OFF;
+			if( pLed->bLedBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedScanBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedWPSBlinkInProgress )
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+
+			SwLedOff(padapter, pLed);
+			break;
+
+		default:
+			break;
+
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+}
+
+  //COREGA, added by chiyoko, 20090316
+ static void
+ SwLedControlMode3(
+	_adapter				*padapter,
+	LED_CTL_MODE		LedAction
+)
+{
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	PLED_SDIO		pLed = &(ledpriv->SwLed0);
+
+	switch(LedAction)
+	{
+		case LED_CTL_SITE_SURVEY:
+			if(pmlmepriv->LinkDetectInfo.bBusyTraffic)
+				;
+			else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+			{
+				if(IS_LED_WPS_BLINKING(pLed))
+					return;
+
+				if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				pLed->bLedScanBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_SCAN;
+				pLed->BlinkTimes = 24;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_TX:
+		case LED_CTL_RX:
+	 		if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+	  		{
+	  		  	if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+				{
+					return;
+				}
+
+				pLed->bLedBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_TXRX;
+				pLed->BlinkTimes = 2;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_LINK:
+			if(IS_LED_WPS_BLINKING(pLed))
+				return;
+
+			pLed->CurrLedState = RTW_LED_ON;
+			pLed->BlinkingLedState = RTW_LED_ON;
+			if( pLed->bLedBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedScanBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+
+			_set_timer(&(pLed->BlinkTimer), 0);
+			break;
+
+		case LED_CTL_START_WPS: //wait until xinpin finish
+		case LED_CTL_START_WPS_BOTTON:
+			if(pLed->bLedWPSBlinkInProgress ==_FALSE)
+			{
+				if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				if(pLed->bLedScanBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedScanBlinkInProgress = _FALSE;
+				}
+				pLed->bLedWPSBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_WPS;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_STOP_WPS:
+			if(pLed->bLedWPSBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+			else
+			{
+				pLed->bLedWPSBlinkInProgress = _TRUE;
+			}
+
+			pLed->CurrLedState = LED_BLINK_WPS_STOP;
+			if(pLed->bLedOn)
+			{
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+			}
+			else
+			{
+				pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), 0);
+			}
+
+			break;
+
+		case LED_CTL_STOP_WPS_FAIL:
+			if(pLed->bLedWPSBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+
+			pLed->CurrLedState = RTW_LED_OFF;
+			pLed->BlinkingLedState = RTW_LED_OFF;
+			_set_timer(&(pLed->BlinkTimer), 0);
+			break;
+
+		case LED_CTL_START_TO_LINK:
+		case LED_CTL_NO_LINK:
+			if(!IS_LED_BLINKING(pLed))
+			{
+				pLed->CurrLedState = RTW_LED_OFF;
+				pLed->BlinkingLedState = RTW_LED_OFF;
+				_set_timer(&(pLed->BlinkTimer), 0);
+			}
+			break;
+
+		case LED_CTL_POWER_OFF:
+			pLed->CurrLedState = RTW_LED_OFF;
+			pLed->BlinkingLedState = RTW_LED_OFF;
+			if( pLed->bLedBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedScanBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedWPSBlinkInProgress )
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+
+			SwLedOff(padapter, pLed);
+			break;
+
+		default:
+			break;
+
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+}
+
+
+ //Edimax-Belkin, added by chiyoko, 20090413
+static void
+SwLedControlMode4(
+	_adapter				*padapter,
+	LED_CTL_MODE		LedAction
+)
+{
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	PLED_SDIO		pLed = &(ledpriv->SwLed0);
+	PLED_SDIO		pLed1 = &(ledpriv->SwLed1);
+
+	switch(LedAction)
+	{
+		case LED_CTL_START_TO_LINK:
+			if(pLed1->bLedWPSBlinkInProgress)
+			{
+				pLed1->bLedWPSBlinkInProgress = _FALSE;
+				_cancel_timer_ex(&(pLed1->BlinkTimer));
+
+				pLed1->BlinkingLedState = RTW_LED_OFF;
+				pLed1->CurrLedState = RTW_LED_OFF;
+
+				if(pLed1->bLedOn)
+					_set_timer(&(pLed->BlinkTimer), 0);
+			}
+
+			if( pLed->bLedStartToLinkBlinkInProgress == _FALSE )
+			{
+				if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+				{
+					return;
+				}
+	 			if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+	 			}
+	 			if(pLed->bLedNoLinkBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+	 			}
+
+				pLed->bLedStartToLinkBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_StartToBlink;
+				if( pLed->bLedOn )
+				{
+					pLed->BlinkingLedState = RTW_LED_OFF;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+				}
+				else
+				{
+					pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+				}
+			}
+			break;
+
+		case LED_CTL_LINK:
+		case LED_CTL_NO_LINK:
+			//LED1 settings
+			if(LedAction == LED_CTL_LINK)
+			{
+				if(pLed1->bLedWPSBlinkInProgress)
+				{
+					pLed1->bLedWPSBlinkInProgress = _FALSE;
+					_cancel_timer_ex(&(pLed1->BlinkTimer));
+
+					pLed1->BlinkingLedState = RTW_LED_OFF;
+					pLed1->CurrLedState = RTW_LED_OFF;
+
+					if(pLed1->bLedOn)
+						_set_timer(&(pLed->BlinkTimer), 0);
+				}
+			}
+
+			if( pLed->bLedNoLinkBlinkInProgress == _FALSE )
+			{
+				if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+				{
+					return;
+				}
+	 			if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+	 			}
+
+				pLed->bLedNoLinkBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_SLOWLY;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_SITE_SURVEY:
+			if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+				;
+			else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+			{
+				if(IS_LED_WPS_BLINKING(pLed))
+					return;
+
+				if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+				}
+				if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				pLed->bLedScanBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_SCAN;
+				pLed->BlinkTimes = 24;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_TX:
+		case LED_CTL_RX:
+	 		if(pLed->bLedBlinkInProgress ==_FALSE)
+	  		{
+	  		  	if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+				{
+					return;
+				}
+	  		  	if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+				}
+				pLed->bLedBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_TXRX;
+				pLed->BlinkTimes = 2;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_START_WPS: //wait until xinpin finish
+		case LED_CTL_START_WPS_BOTTON:
+			if(pLed1->bLedWPSBlinkInProgress)
+			{
+				pLed1->bLedWPSBlinkInProgress = _FALSE;
+				_cancel_timer_ex(&(pLed1->BlinkTimer));
+
+				pLed1->BlinkingLedState = RTW_LED_OFF;
+				pLed1->CurrLedState = RTW_LED_OFF;
+
+				if(pLed1->bLedOn)
+					_set_timer(&(pLed->BlinkTimer), 0);
+			}
+
+			if(pLed->bLedWPSBlinkInProgress ==_FALSE)
+			{
+				if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedNoLinkBlinkInProgress = _FALSE;
+				}
+				if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				if(pLed->bLedScanBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedScanBlinkInProgress = _FALSE;
+				}
+				pLed->bLedWPSBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_WPS;
+				if( pLed->bLedOn )
+				{
+					pLed->BlinkingLedState = RTW_LED_OFF;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+				}
+				else
+				{
+					pLed->BlinkingLedState = RTW_LED_ON;
+					_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+				}
+			}
+			break;
+
+		case LED_CTL_STOP_WPS:	//WPS connect success
+			if(pLed->bLedWPSBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+
+			pLed->bLedNoLinkBlinkInProgress = _TRUE;
+			pLed->CurrLedState = LED_BLINK_SLOWLY;
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+			break;
+
+		case LED_CTL_STOP_WPS_FAIL:		//WPS authentication fail
+			if(pLed->bLedWPSBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+
+			pLed->bLedNoLinkBlinkInProgress = _TRUE;
+			pLed->CurrLedState = LED_BLINK_SLOWLY;
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+			//LED1 settings
+			if(pLed1->bLedWPSBlinkInProgress)
+				_cancel_timer_ex(&(pLed1->BlinkTimer));
+			else
+				pLed1->bLedWPSBlinkInProgress = _TRUE;
+
+			pLed1->CurrLedState = LED_BLINK_WPS_STOP;
+			if( pLed1->bLedOn )
+				pLed1->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed1->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+
+			break;
+
+		case LED_CTL_STOP_WPS_FAIL_OVERLAP:	//WPS session overlap
+			if(pLed->bLedWPSBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+
+			pLed->bLedNoLinkBlinkInProgress = _TRUE;
+			pLed->CurrLedState = LED_BLINK_SLOWLY;
+			if( pLed->bLedOn )
+				pLed->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+			//LED1 settings
+			if(pLed1->bLedWPSBlinkInProgress)
+				_cancel_timer_ex(&(pLed1->BlinkTimer));
+			else
+				pLed1->bLedWPSBlinkInProgress = _TRUE;
+
+			pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
+			pLed1->BlinkTimes = 10;
+			if( pLed1->bLedOn )
+				pLed1->BlinkingLedState = RTW_LED_OFF;
+			else
+				pLed1->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+
+			break;
+
+		case LED_CTL_POWER_OFF:
+			pLed->CurrLedState = RTW_LED_OFF;
+			pLed->BlinkingLedState = RTW_LED_OFF;
+
+			if( pLed->bLedNoLinkBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedNoLinkBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedLinkBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedLinkBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedWPSBlinkInProgress )
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedWPSBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedScanBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedScanBlinkInProgress = _FALSE;
+			}
+			if( pLed->bLedStartToLinkBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedStartToLinkBlinkInProgress = _FALSE;
+			}
+
+			if( pLed1->bLedWPSBlinkInProgress )
+			{
+				_cancel_timer_ex(&(pLed1->BlinkTimer));
+				pLed1->bLedWPSBlinkInProgress = _FALSE;
+			}
+
+			pLed1->BlinkingLedState = LED_UNKNOWN;
+			SwLedOff(padapter, pLed);
+			SwLedOff(padapter, pLed1);
+			break;
+
+		default:
+			break;
+
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
+}
+
+
+
+ //Sercomm-Belkin, added by chiyoko, 20090415
+static void
+SwLedControlMode5(
+	_adapter				*padapter,
+	LED_CTL_MODE		LedAction
+)
+{
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PLED_SDIO		pLed = &(ledpriv->SwLed0);
+
+	if(pHalData->CustomerID == RT_CID_819x_CAMEO)
+		pLed = &(ledpriv->SwLed1);
+
+	switch(LedAction)
+	{
+		case LED_CTL_POWER_ON:
+		case LED_CTL_NO_LINK:
+		case LED_CTL_LINK: 	//solid blue
+			pLed->CurrLedState = RTW_LED_ON;
+			pLed->BlinkingLedState = RTW_LED_ON;
+
+			_set_timer(&(pLed->BlinkTimer), 0);
+			break;
+
+		case LED_CTL_SITE_SURVEY:
+			if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+				;
+			else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+			{
+				if(pLed->bLedBlinkInProgress ==_TRUE)
+				{
+					_cancel_timer_ex(&(pLed->BlinkTimer));
+					pLed->bLedBlinkInProgress = _FALSE;
+				}
+				pLed->bLedScanBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_SCAN;
+				pLed->BlinkTimes = 24;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_TX:
+		case LED_CTL_RX:
+	 		if(pLed->bLedBlinkInProgress ==_FALSE)
+	  		{
+	  		  	if(pLed->CurrLedState == LED_BLINK_SCAN)
+				{
+					return;
+				}
+				pLed->bLedBlinkInProgress = _TRUE;
+				pLed->CurrLedState = LED_BLINK_TXRX;
+				pLed->BlinkTimes = 2;
+				if( pLed->bLedOn )
+					pLed->BlinkingLedState = RTW_LED_OFF;
+				else
+					pLed->BlinkingLedState = RTW_LED_ON;
+				_set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+			}
+			break;
+
+		case LED_CTL_POWER_OFF:
+			pLed->CurrLedState = RTW_LED_OFF;
+			pLed->BlinkingLedState = RTW_LED_OFF;
+
+			if( pLed->bLedBlinkInProgress)
+			{
+				_cancel_timer_ex(&(pLed->BlinkTimer));
+				pLed->bLedBlinkInProgress = _FALSE;
+			}
+
+			SwLedOff(padapter, pLed);
+			break;
+
+		default:
+			break;
+
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
+}
+
+ //WNC-Corega, added by chiyoko, 20090902
+static void
+SwLedControlMode6(
+	_adapter				*padapter,
+	LED_CTL_MODE		LedAction
+)
+{
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+	PLED_SDIO pLed0 = &(ledpriv->SwLed0);
+
+	switch(LedAction)
+	{
+		case LED_CTL_POWER_ON:
+		case LED_CTL_LINK:
+		case LED_CTL_NO_LINK:
+			_cancel_timer_ex(&(pLed0->BlinkTimer));
+			pLed0->CurrLedState = RTW_LED_ON;
+			pLed0->BlinkingLedState = RTW_LED_ON;
+			_set_timer(&(pLed0->BlinkTimer), 0);
+			break;
+
+		case LED_CTL_POWER_OFF:
+			SwLedOff(padapter, pLed0);
+			break;
+
+		default:
+			break;
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("ledcontrol 6 Led %d\n", pLed0->CurrLedState));
+}
+
+void
+LedControlSDIO(
+	_adapter				*padapter,
+	LED_CTL_MODE		LedAction
+	)
+{
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+
+ #if(MP_DRIVER == 1)
+	if (padapter->registrypriv.mp_mode == 1)
+		return;
+#endif
+
+	if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) {
+		/*DBG_871X("%s bDriverStopped:%s, bSurpriseRemoved:%s\n"
+		, __func__
+		, rtw_is_drv_stopped(padapter)?"True":"False"
+		, rtw_is_surprise_removed(padapter)?"True":"False");*/
+		return;
+	}
+
+	if( ledpriv->bRegUseLed == _FALSE)
+		return;
+
+	//if(priv->bInHctTest)
+	//	return;
+
+#ifdef CONFIG_CONCURRENT_MODE
+	// Only do led action for PRIMARY_ADAPTER
+	if (padapter->adapter_type != PRIMARY_ADAPTER)
+		return;
+#endif
+
+	if( (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on &&
+		adapter_to_pwrctl(padapter)->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_POWER_ON) )
+	{
+		return;
+	}
+
+	switch(ledpriv->LedStrategy)
+	{
+		case SW_LED_MODE0:
+			SwLedControlMode0(padapter, LedAction);
+			break;
+
+		case SW_LED_MODE1:
+			SwLedControlMode1(padapter, LedAction);
+			break;
+		case SW_LED_MODE2:
+			SwLedControlMode2(padapter, LedAction);
+                	break;
+
+		case SW_LED_MODE3:
+			SwLedControlMode3(padapter, LedAction);
+			break;
+
+		case SW_LED_MODE4:
+			SwLedControlMode4(padapter, LedAction);
+			break;
+
+		case SW_LED_MODE5:
+			SwLedControlMode5(padapter, LedAction);
+			break;
+
+		case SW_LED_MODE6:
+			SwLedControlMode6(padapter, LedAction);
+			break;
+
+		default:
+			break;
+	}
+
+	RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("LedStrategy:%d, LedAction %d\n", ledpriv->LedStrategy,LedAction));
+}
+
+//
+//	Description:
+//		Reset status of LED_871x object.
+//
+void ResetLedStatus(PLED_SDIO pLed) {
+
+	pLed->CurrLedState = RTW_LED_OFF; // Current LED state.
+	pLed->bLedOn = _FALSE; // true if LED is ON, false if LED is OFF.
+
+	pLed->bLedBlinkInProgress = _FALSE; // true if it is blinking, false o.w..
+	pLed->bLedWPSBlinkInProgress = _FALSE;
+	
+	pLed->BlinkTimes = 0; // Number of times to toggle led state for blinking.
+	pLed->BlinkingLedState = LED_UNKNOWN; // Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are.
+
+	pLed->bLedNoLinkBlinkInProgress = _FALSE;
+	pLed->bLedLinkBlinkInProgress = _FALSE;
+	pLed->bLedStartToLinkBlinkInProgress = _FALSE;
+	pLed->bLedScanBlinkInProgress = _FALSE;
+}
+
+ //
+//	Description:
+//		Initialize an LED_871x object.
+//
+void
+InitLed(
+	_adapter			*padapter,
+	PLED_SDIO		pLed,
+	LED_PIN			LedPin
+	)
+{
+	pLed->padapter = padapter;
+	pLed->LedPin = LedPin;
+
+	ResetLedStatus(pLed);
+
+	timer_setup(&(pLed->BlinkTimer), BlinkTimerCallback, 0);
+
+	_init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed);
+}
+
+
+//
+//	Description:
+//		DeInitialize an LED_871x object.
+//
+void
+DeInitLed(
+	PLED_SDIO		pLed
+	)
+{
+	_cancel_workitem_sync(&(pLed->BlinkWorkItem));
+	_cancel_timer_ex(&(pLed->BlinkTimer));
+	ResetLedStatus(pLed);
+}
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/Hal8703BPwrSeq.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/Hal8703BPwrSeq.c
new file mode 100644
index 000000000..60f7a9b0e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/Hal8703BPwrSeq.c
@@ -0,0 +1,94 @@
+
+/*++
+Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+
+Module Name:
+	Hal8703BPwrSeq.c
+	
+Abstract:
+	This file includes all kinds of Power Action event for RTL8703B and corresponding hardware configurtions which are released from HW SD.
+	    
+Major Change History:
+	When       Who               What
+	---------- ---------------   -------------------------------
+	2014-12-24 Ivan                      Version1
+	
+--*/
+
+#include "Hal8703BPwrSeq.h"
+
+
+/* 
+    drivers should parse below arrays and do the corresponding actions
+*/
+//3 Power on  Array
+WLAN_PWR_CFG rtl8703B_power_on_flow[RTL8703B_TRANS_CARDEMU_TO_ACT_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	RTL8703B_TRANS_CARDEMU_TO_ACT
+	RTL8703B_TRANS_END
+};
+
+//3Radio off GPIO Array
+WLAN_PWR_CFG rtl8703B_radio_off_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	RTL8703B_TRANS_ACT_TO_CARDEMU
+	RTL8703B_TRANS_END
+};
+
+//3Card Disable Array
+WLAN_PWR_CFG rtl8703B_card_disable_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	RTL8703B_TRANS_ACT_TO_CARDEMU
+	RTL8703B_TRANS_CARDEMU_TO_CARDDIS
+	RTL8703B_TRANS_END
+};
+
+//3 Card Enable Array
+WLAN_PWR_CFG rtl8703B_card_enable_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	RTL8703B_TRANS_CARDDIS_TO_CARDEMU
+	RTL8703B_TRANS_CARDEMU_TO_ACT		
+	RTL8703B_TRANS_END
+};
+
+//3Suspend Array
+WLAN_PWR_CFG rtl8703B_suspend_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_SUS_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	RTL8703B_TRANS_ACT_TO_CARDEMU
+	RTL8703B_TRANS_CARDEMU_TO_SUS
+	RTL8703B_TRANS_END
+};
+
+//3 Resume Array
+WLAN_PWR_CFG rtl8703B_resume_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_SUS_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	RTL8703B_TRANS_SUS_TO_CARDEMU
+	RTL8703B_TRANS_CARDEMU_TO_ACT
+	RTL8703B_TRANS_END
+};
+
+
+
+//3HWPDN Array
+WLAN_PWR_CFG rtl8703B_hwpdn_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	RTL8703B_TRANS_ACT_TO_CARDEMU
+	RTL8703B_TRANS_CARDEMU_TO_PDN		
+	RTL8703B_TRANS_END
+};
+
+//3 Enter LPS 
+WLAN_PWR_CFG rtl8703B_enter_lps_flow[RTL8703B_TRANS_ACT_TO_LPS_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	//FW behavior
+	RTL8703B_TRANS_ACT_TO_LPS	
+	RTL8703B_TRANS_END
+};
+
+//3 Leave LPS 
+WLAN_PWR_CFG rtl8703B_leave_lps_flow[RTL8703B_TRANS_LPS_TO_ACT_STEPS+RTL8703B_TRANS_END_STEPS]=
+{
+	//FW behavior
+	RTL8703B_TRANS_LPS_TO_ACT
+	RTL8703B_TRANS_END
+};
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_cmd.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_cmd.c
new file mode 100644
index 000000000..99dfc72d0
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_cmd.c
@@ -0,0 +1,1373 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *
+ ******************************************************************************/
+#define _RTL8703B_CMD_C_
+
+#include <rtl8703b_hal.h>
+#include "hal_com_h2c.h"
+
+#define MAX_H2C_BOX_NUMS	4
+#define MESSAGE_BOX_SIZE		4
+
+#define RTL8703B_MAX_CMD_LEN	7
+#define RTL8703B_EX_MESSAGE_BOX_SIZE	4
+
+static u8 _is_fw_read_cmd_down(_adapter* padapter, u8 msgbox_num)
+{
+	u8	read_down = _FALSE;
+	int 	retry_cnts = 100;
+
+	u8 valid;
+
+	//DBG_8192C(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num);
+
+	do{
+		valid = rtw_read8(padapter,REG_HMETFR) & BIT(msgbox_num);
+		if(0 == valid ){
+			read_down = _TRUE;
+		}
+		else
+			rtw_msleep_os(1);
+	}while( (!read_down) && (retry_cnts--));
+
+	return read_down;
+
+}
+
+
+/*****************************************
+* H2C Msg format :
+*| 31 - 8		|7-5	| 4 - 0	|
+*| h2c_msg 	|Class	|CMD_ID	|
+*| 31-0						|
+*| Ext msg					|
+*
+******************************************/
+s32 FillH2CCmd8703B(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
+{
+	u8 h2c_box_num;
+	u32	msgbox_addr;
+	u32 msgbox_ex_addr=0;
+	PHAL_DATA_TYPE pHalData;
+	u32	h2c_cmd = 0;
+	u32	h2c_cmd_ex = 0;
+	s32 ret = _FAIL;
+	struct dvobj_priv *psdpriv = padapter->dvobj;
+	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+_func_enter_;
+
+	padapter = GET_PRIMARY_ADAPTER(padapter);
+	pHalData = GET_HAL_DATA(padapter);
+#ifdef DBG_CHECK_FW_PS_STATE
+#ifdef DBG_CHECK_FW_PS_STATE_H2C
+	if(rtw_fw_ps_state(padapter) == _FAIL)
+	{
+		DBG_871X("%s: h2c doesn't leave 32k ElementID=%02x \n", __FUNCTION__, ElementID);
+		pdbgpriv->dbg_h2c_leave32k_fail_cnt++;
+	}
+
+	//DBG_871X("H2C ElementID=%02x , pHalData->LastHMEBoxNum=%02x\n", ElementID, pHalData->LastHMEBoxNum);
+#endif //DBG_CHECK_FW_PS_STATE_H2C
+#endif //DBG_CHECK_FW_PS_STATE
+	_enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
+
+	if (!pCmdBuffer) {
+		goto exit;
+	}
+	if(CmdLen > RTL8703B_MAX_CMD_LEN) {
+		goto exit;
+	}
+	if (rtw_is_surprise_removed(padapter))
+		goto exit;
+
+	//pay attention to if  race condition happened in  H2C cmd setting.
+	do{
+		h2c_box_num = pHalData->LastHMEBoxNum;
+
+		if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){
+			DBG_8192C(" fw read cmd failed...\n");
+#ifdef DBG_CHECK_FW_PS_STATE
+			DBG_871X("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n", rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
+				, rtw_read32(padapter, 0x1c8), rtw_read32(padapter, 0x1cc));
+#endif //DBG_CHECK_FW_PS_STATE
+			//DBG_8192C(" 0x1c0: 0x%8x\n", rtw_read32(padapter, 0x1c0));
+			//DBG_8192C(" 0x1c4: 0x%8x\n", rtw_read32(padapter, 0x1c4));
+			goto exit;
+		}
+
+		if(CmdLen<=3)
+		{
+			_rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen );
+		}
+		else{
+			_rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, 3);
+			_rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3, CmdLen-3);
+//			*(u8*)(&h2c_cmd) |= BIT(7);
+		}
+
+		*(u8*)(&h2c_cmd) |= ElementID;
+
+		if(CmdLen>3){
+			msgbox_ex_addr = REG_HMEBOX_EXT0_8703B + (h2c_box_num *RTL8703B_EX_MESSAGE_BOX_SIZE);
+			h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex );
+			rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);
+		}
+		msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *MESSAGE_BOX_SIZE);
+		h2c_cmd = le32_to_cpu( h2c_cmd );
+		rtw_write32(padapter,msgbox_addr, h2c_cmd);
+
+		//DBG_8192C("MSG_BOX:%d, CmdLen(%d), CmdID(0x%x), reg:0x%x =>h2c_cmd:0x%.8x, reg:0x%x =>h2c_cmd_ex:0x%.8x\n"
+		// 	,pHalData->LastHMEBoxNum , CmdLen, ElementID, msgbox_addr, h2c_cmd, msgbox_ex_addr, h2c_cmd_ex);
+
+		pHalData->LastHMEBoxNum = (h2c_box_num+1) % MAX_H2C_BOX_NUMS;
+
+	}while(0);
+
+	ret = _SUCCESS;
+
+exit:
+
+	_exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);	
+
+_func_exit_;
+
+	return ret;
+}
+
+static void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16					*fctrl;
+	u32					rate_len, pktlen;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
+	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+
+	//DBG_871X("%s\n", __FUNCTION__);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+
+	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+
+	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
+	//pmlmeext->mgnt_seq++;
+	SetFrameSubType(pframe, WIFI_BEACON);
+
+	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+	pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
+
+	//timestamp will be inserted by hardware
+	pframe += 8;
+	pktlen += 8;
+
+	// beacon interval: 2 bytes
+	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
+
+	pframe += 2;
+	pktlen += 2;
+
+	// capability info: 2 bytes
+	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
+
+	pframe += 2;
+	pktlen += 2;
+
+	if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
+	{
+		//DBG_871X("ie len=%d\n", cur_network->IELength);
+		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
+		_rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);
+
+		goto _ConstructBeacon;
+	}
+
+	//below for ad-hoc mode
+
+	// SSID
+	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
+
+	// supported rates...
+	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
+	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
+
+	// DS parameter set
+	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
+
+	if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
+	{
+		u32 ATIMWindow;
+		// IBSS Parameter Set...
+		//ATIMWindow = cur->Configuration.ATIMWindow;
+		ATIMWindow = 0;
+		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
+	}
+
+
+	//todo: ERP IE
+
+
+	// EXTERNDED SUPPORTED RATE
+	if (rate_len > 8)
+	{
+		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
+	}
+
+
+	//todo:HT for adhoc
+
+_ConstructBeacon:
+
+	if ((pktlen + TXDESC_SIZE) > 512)
+	{
+		DBG_871X("beacon frame too large\n");
+		return;
+	}
+
+	*pLength = pktlen;
+
+	//DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen);
+
+}
+
+static void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16					*fctrl;
+	u32					pktlen;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+
+	//DBG_871X("%s\n", __FUNCTION__);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+	// Frame control.
+	fctrl = &(pwlanhdr->frame_ctl);
+	*(fctrl) = 0;
+	SetPwrMgt(fctrl);
+	SetFrameSubType(pframe, WIFI_PSPOLL);
+
+	// AID.
+	SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
+
+	// BSSID.
+	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+	// TA.
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+
+	*pLength = 16;
+}
+
+static void ConstructNullFunctionData(
+	PADAPTER padapter,
+	u8		*pframe,
+	u32		*pLength,
+	u8		*StaAddr,
+	u8		bQoS,
+	u8		AC,
+	u8		bEosp,
+	u8		bForcePowerSave)
+{
+	struct rtw_ieee80211_hdr	*pwlanhdr;
+	u16						*fctrl;
+	u32						pktlen;
+	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
+	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+
+
+	//DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
+
+	fctrl = &pwlanhdr->frame_ctl;
+	*(fctrl) = 0;
+	if (bForcePowerSave)
+	{
+		SetPwrMgt(fctrl);
+	}
+
+	switch(cur_network->network.InfrastructureMode)
+	{
+		case Ndis802_11Infrastructure:
+			SetToDs(fctrl);
+			_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
+			break;
+		case Ndis802_11APMode:
+			SetFrDs(fctrl);
+			_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+			break;
+		case Ndis802_11IBSS:
+		default:
+			_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+			_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+			break;
+	}
+
+	SetSeqNum(pwlanhdr, 0);
+
+	if (bQoS == _TRUE) {
+		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
+
+		SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
+
+		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
+		SetPriority(&pwlanqoshdr->qc, AC);
+		SetEOSP(&pwlanqoshdr->qc, bEosp);
+
+		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
+	} else {
+		SetFrameSubType(pframe, WIFI_DATA_NULL);
+
+		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+	}
+
+	*pLength = pktlen;
+}
+
+// To check if reserved page content is destroyed by beacon beacuse beacon is too large.
+// 2010.06.23. Added by tynli.
+VOID
+CheckFwRsvdPageContent(
+	IN	PADAPTER		Adapter
+)
+{
+	HAL_DATA_TYPE*	pHalData = GET_HAL_DATA(Adapter);
+	u32	MaxBcnPageNum;
+
+ 	if(pHalData->FwRsvdPageStartOffset != 0)
+ 	{
+ 		/*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize);
+		RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset),
+			("CheckFwRsvdPageContent(): The reserved page content has been"\
+			"destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!",
+			MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/
+ 	}
+}
+
+//
+// Description: Get the reserved page number in Tx packet buffer.
+// Retrun value: the page number.
+// 2012.08.09, by tynli.
+//
+u8 GetTxBufferRsvdPageNum8703B(_adapter *padapter, bool wowlan)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u8	RsvdPageNum=0;
+	// default reseved 1 page for the IC type which is undefined.
+	u8	TxPageBndy= LAST_ENTRY_OF_TX_PKT_BUFFER_8703B;
+
+	rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&TxPageBndy);
+
+	RsvdPageNum = LAST_ENTRY_OF_TX_PKT_BUFFER_8703B -TxPageBndy + 1;
+
+	return RsvdPageNum;
+}
+
+static void rtl8703b_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+	u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0};
+
+	DBG_871X("8703BRsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",  
+		rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
+		rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
+		rsvdpageloc->LocBTQosNull);
+
+	SET_8703B_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
+	SET_8703B_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
+	SET_8703B_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
+	SET_8703B_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
+	SET_8703B_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
+	
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CRsvdPageParm:", u1H2CRsvdPageParm, H2C_RSVDPAGE_LOC_LEN);
+	FillH2CCmd8703B(padapter, H2C_8703B_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm);
+}
+
+static void rtl8703b_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+	u8	res = 0, count = 0;
+#ifdef CONFIG_WOWLAN	
+	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
+
+	DBG_871X("8703BAOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",  
+			rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
+			rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
+			rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
+			rsvdpageloc->LocNetList);
+
+	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
+		//SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv);
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
+#ifdef CONFIG_GTK_OL
+		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
+#endif // CONFIG_GTK_OL
+		RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CAoacRsvdPageParm:", u1H2CAoacRsvdPageParm, H2C_AOAC_RSVDPAGE_LOC_LEN);
+		FillH2CCmd8703B(padapter, H2C_8703B_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);
+	} else {
+#ifdef CONFIG_PNO_SUPPORT
+		if(!pwrpriv->pno_in_resume) {
+			DBG_871X("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
+			_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
+			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocPNOInfo);
+			FillH2CCmd8703B(padapter, H2C_AOAC_RSVDPAGE3, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);
+			rtw_msleep_os(10);
+		}
+#endif
+	}
+
+#endif // CONFIG_WOWLAN
+}
+
+static void rtl8703b_set_FwKeepAlive_cmd(PADAPTER padapter, u8 benable, u8 pkt_type)
+{
+	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN]={0};
+	u8 adopt = 1;
+#ifdef CONFIG_PLATFORM_INTEL_BYT
+        u8 check_period = 10;
+#else
+        u8 check_period = 5;
+#endif 
+
+	DBG_871X("%s(): benable = %d\n", __func__, benable);
+	SET_8703B_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, benable);
+	SET_8703B_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
+	SET_8703B_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
+	SET_8703B_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CKeepAliveParm:", u1H2CKeepAliveParm, H2C_KEEP_ALIVE_CTRL_LEN);
+
+	FillH2CCmd8703B(padapter, H2C_8703B_KEEP_ALIVE, H2C_KEEP_ALIVE_CTRL_LEN, u1H2CKeepAliveParm);
+}
+
+static void rtl8703b_set_FwDisconDecision_cmd(PADAPTER padapter, u8 benable)
+{
+	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN]={0};
+	u8 adopt = 1, check_period = 10, trypkt_num = 0;
+
+	DBG_871X("%s(): benable = %d\n", __func__, benable);
+	SET_8703B_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, benable);
+	SET_8703B_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
+	SET_8703B_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
+	SET_8703B_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CDisconDecisionParm:", u1H2CDisconDecisionParm, H2C_DISCON_DECISION_LEN);
+
+	FillH2CCmd8703B(padapter, H2C_8703B_DISCON_DECISION, H2C_DISCON_DECISION_LEN, u1H2CDisconDecisionParm);
+}
+
+void rtl8703b_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u8 u1H2CMacIdConfigParm[H2C_MACID_CFG_LEN]={0};
+
+	DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask);
+	
+_func_enter_;
+
+	SET_8703B_H2CCMD_MACID_CFG_MACID(u1H2CMacIdConfigParm, mac_id);
+	SET_8703B_H2CCMD_MACID_CFG_RAID(u1H2CMacIdConfigParm, raid);
+	SET_8703B_H2CCMD_MACID_CFG_SGI_EN(u1H2CMacIdConfigParm, (sgi)? 1:0);
+	SET_8703B_H2CCMD_MACID_CFG_BW(u1H2CMacIdConfigParm, bw);
+
+	//DisableTXPowerTraining
+	if(pHalData->bDisableTXPowerTraining){
+		SET_8703B_H2CCMD_MACID_CFG_DISPT(u1H2CMacIdConfigParm,1);
+		DBG_871X("%s,Disable PWT by driver\n",__FUNCTION__);
+	}
+	else{
+		PDM_ODM_T	pDM_OutSrc = &pHalData->odmpriv;
+
+		if(pDM_OutSrc->bDisablePowerTraining){
+			SET_8703B_H2CCMD_MACID_CFG_DISPT(u1H2CMacIdConfigParm,1);
+			DBG_871X("%s,Disable PWT by DM\n",__FUNCTION__);	
+		}
+	}	
+		
+	SET_8703B_H2CCMD_MACID_CFG_RATE_MASK0(u1H2CMacIdConfigParm, (u8)(mask & 0x000000ff));
+	SET_8703B_H2CCMD_MACID_CFG_RATE_MASK1(u1H2CMacIdConfigParm, (u8)((mask & 0x0000ff00) >>8));
+	SET_8703B_H2CCMD_MACID_CFG_RATE_MASK2(u1H2CMacIdConfigParm, (u8)((mask & 0x00ff0000) >> 16));
+	SET_8703B_H2CCMD_MACID_CFG_RATE_MASK3(u1H2CMacIdConfigParm, (u8)((mask & 0xff000000) >> 24));
+	
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CMacIdConfigParm:", u1H2CMacIdConfigParm, H2C_MACID_CFG_LEN);
+	FillH2CCmd8703B(padapter, H2C_8703B_MACID_CFG, H2C_MACID_CFG_LEN, u1H2CMacIdConfigParm);
+
+_func_exit_;
+}
+
+void rtl8703b_set_FwRssiSetting_cmd(_adapter*padapter, u8 *param)
+{
+	u8 u1H2CRssiSettingParm[H2C_RSSI_SETTING_LEN]={0};
+	u8 mac_id = *param;
+	u8 rssi = *(param+2);
+	u8 uldl_state = 0;
+
+_func_enter_;
+	//DBG_871X("%s(): param=%.2x-%.2x-%.2x\n", __func__, *param, *(param+1), *(param+2));
+	//DBG_871X("%s(): mac_id=%d rssi=%d\n", __func__, mac_id, rssi);
+
+	SET_8703B_H2CCMD_RSSI_SETTING_MACID(u1H2CRssiSettingParm, mac_id);
+	SET_8703B_H2CCMD_RSSI_SETTING_RSSI(u1H2CRssiSettingParm, rssi);
+	SET_8703B_H2CCMD_RSSI_SETTING_ULDL_STATE(u1H2CRssiSettingParm, uldl_state);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "u1H2CRssiSettingParm:", u1H2CRssiSettingParm, H2C_RSSI_SETTING_LEN);
+	FillH2CCmd8703B(padapter, H2C_8703B_RSSI_SETTING, H2C_RSSI_SETTING_LEN, u1H2CRssiSettingParm);
+
+_func_exit_;
+}
+
+void rtl8703b_set_FwAPReqRPT_cmd(PADAPTER padapter, u32 need_ack)
+{
+	u8 u1H2CApReqRptParm[H2C_AP_REQ_TXRPT_LEN]={0};
+	u8 macid1 = 1, macid2 = 0;
+
+	DBG_871X("%s(): need_ack = %d\n", __func__, need_ack);
+
+	SET_8703B_H2CCMD_APREQRPT_PARM_MACID1(u1H2CApReqRptParm, macid1);
+	SET_8703B_H2CCMD_APREQRPT_PARM_MACID2(u1H2CApReqRptParm, macid2);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CApReqRptParm:", u1H2CApReqRptParm, H2C_AP_REQ_TXRPT_LEN);
+	FillH2CCmd8703B(padapter, H2C_8703B_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm);
+}
+
+void rtl8703b_set_FwPwrMode_cmd(PADAPTER padapter, u8 psmode)
+{
+	int i;
+	u8 smart_ps = 0;
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
+	u8 u1H2CPwrModeParm[H2C_PWRMODE_LEN]={0};
+	u8 PowerState=0, awake_intvl = 1, byte5 = 0, rlbm = 0;
+#ifdef CONFIG_P2P
+	struct wifidirect_info *wdinfo = &(padapter->wdinfo);
+#endif // CONFIG_P2P
+
+_func_enter_;
+
+#ifdef CONFIG_PLATFORM_INTEL_BYT
+        if(psmode == PS_MODE_DTIM)
+                psmode = PS_MODE_MAX;
+#endif //CONFIG_PLATFORM_INTEL_BYT
+
+
+	if(pwrpriv->dtim > 0)
+		DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d, dtim=%d\n", __func__, psmode, pwrpriv->smart_ps, pwrpriv->dtim);
+	else
+		DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d\n", __func__, psmode, pwrpriv->smart_ps);
+
+	if(psmode == PS_MODE_MIN)
+	{
+		rlbm = 0;
+		awake_intvl = 2;
+		smart_ps = pwrpriv->smart_ps;
+	}
+	else if(psmode == PS_MODE_MAX)
+	{
+		rlbm = 1;
+		awake_intvl = 2;
+		smart_ps = pwrpriv->smart_ps;
+	}
+	else if(psmode == PS_MODE_DTIM) //For WOWLAN LPS, DTIM = (awake_intvl - 1)
+	{
+		if(pwrpriv->dtim > 0 && pwrpriv->dtim < 16)
+			awake_intvl = pwrpriv->dtim+1;//DTIM = (awake_intvl - 1)
+		else
+			awake_intvl = 4;//DTIM=3
+
+
+		rlbm = 2;
+		smart_ps = pwrpriv->smart_ps;
+	}
+	else
+	{
+		rlbm = 2;
+		awake_intvl = 4;
+		smart_ps = pwrpriv->smart_ps;
+	}	
+
+#ifdef CONFIG_P2P
+	if (!rtw_p2p_chk_state(wdinfo, P2P_STATE_NONE)) {
+		awake_intvl = 2;
+		rlbm = 1;
+	}
+#endif // CONFIG_P2P
+
+	if(padapter->registrypriv.wifi_spec==1)
+	{
+		awake_intvl = 2;
+		rlbm = 1;
+	}
+
+	if (psmode > 0)
+	{
+#ifdef CONFIG_BT_COEXIST
+		if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)
+		{
+			PowerState = rtw_btcoex_RpwmVal(padapter);
+			byte5 = rtw_btcoex_LpsVal(padapter);
+
+			if ((rlbm == 2) && (byte5 & BIT(4)))
+			{
+				// Keep awake interval to 1 to prevent from
+				// decreasing coex performance
+				awake_intvl = 2;
+				rlbm = 2;
+			}
+		}
+		else
+#endif // CONFIG_BT_COEXIST
+		{
+			PowerState = 0x00;// AllON(0x0C), RFON(0x04), RFOFF(0x00)
+			byte5 = 0x40;
+		}
+	}
+	else
+	{
+		PowerState = 0x0C;// AllON(0x0C), RFON(0x04), RFOFF(0x00)
+		byte5 = 0x40;
+	}
+
+	SET_8703B_H2CCMD_PWRMODE_PARM_MODE(u1H2CPwrModeParm, (psmode>0)?1:0);
+	SET_8703B_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CPwrModeParm, smart_ps);
+	SET_8703B_H2CCMD_PWRMODE_PARM_RLBM(u1H2CPwrModeParm, rlbm);
+	SET_8703B_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CPwrModeParm, awake_intvl);
+	SET_8703B_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CPwrModeParm, padapter->registrypriv.uapsd_enable);
+	SET_8703B_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CPwrModeParm, PowerState);
+	SET_8703B_H2CCMD_PWRMODE_PARM_BYTE5(u1H2CPwrModeParm, byte5);
+#ifdef CONFIG_LPS_LCLK
+	if(psmode != PS_MODE_ACTIVE)
+	{
+		if(pmlmeext ->adaptive_tsf_done == _FALSE && pmlmeext->bcn_cnt>0)
+		{
+			u8 ratio_20_delay, ratio_80_delay;
+
+			//byte 6 for adaptive_early_32k
+			//[0:3] = DrvBcnEarly  (ms) , [4:7] = DrvBcnTimeOut  (ms)
+			// 20% for DrvBcnEarly, 80% for DrvBcnTimeOut
+			ratio_20_delay = 0;
+			ratio_80_delay = 0;
+			pmlmeext->DrvBcnEarly = 0xff;
+			pmlmeext->DrvBcnTimeOut = 0xff;
+
+			//DBG_871X("%s(): bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt);
+
+			for(i=0; i<9; i++)
+			{
+				pmlmeext->bcn_delay_ratio[i] = (pmlmeext->bcn_delay_cnt[i] * 100) /pmlmeext->bcn_cnt;
+
+				//DBG_871X("%s(): bcn_delay_cnt[%d]=%d, bcn_delay_ratio[%d] = %d\n", __func__, i, pmlmeext->bcn_delay_cnt[i]
+				//	,i ,pmlmeext->bcn_delay_ratio[i]);
+	
+				ratio_20_delay += pmlmeext->bcn_delay_ratio[i];
+				ratio_80_delay += pmlmeext->bcn_delay_ratio[i];
+
+				if(ratio_20_delay > 20 && pmlmeext->DrvBcnEarly == 0xff)
+				{
+					pmlmeext->DrvBcnEarly = i;
+					//DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly);
+				}	
+
+				if(ratio_80_delay > 80 && pmlmeext->DrvBcnTimeOut == 0xff)
+				{
+					pmlmeext->DrvBcnTimeOut = i;
+					//DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut);
+				}
+
+				//reset adaptive_early_32k cnt
+				pmlmeext->bcn_delay_cnt[i] = 0;
+				pmlmeext->bcn_delay_ratio[i] = 0;
+			
+			}
+
+			pmlmeext->bcn_cnt = 0;
+			pmlmeext ->adaptive_tsf_done = _TRUE;
+
+		}
+		else
+		{
+			//DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly);
+			//DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut);
+		}
+
+/* offload to FW if fw version > v15.10
+		pmlmeext->DrvBcnEarly=0;
+		pmlmeext->DrvBcnTimeOut=7;
+
+		if((pmlmeext->DrvBcnEarly!=0Xff) && (pmlmeext->DrvBcnTimeOut!=0xff))
+			u1H2CPwrModeParm[H2C_PWRMODE_LEN-1] = BIT(0) | ((pmlmeext->DrvBcnEarly<<1)&0x0E) |((pmlmeext->DrvBcnTimeOut<<4)&0xf0) ;
+*/
+
+	}
+#endif
+
+#ifdef CONFIG_BT_COEXIST
+	rtw_btcoex_RecordPwrMode(padapter, u1H2CPwrModeParm, H2C_PWRMODE_LEN);
+#endif // CONFIG_BT_COEXIST
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPwrModeParm:", u1H2CPwrModeParm, H2C_PWRMODE_LEN);
+
+	FillH2CCmd8703B(padapter, H2C_8703B_SET_PWR_MODE, H2C_PWRMODE_LEN, u1H2CPwrModeParm);
+_func_exit_;
+}
+
+void rtl8703b_set_FwPsTuneParam_cmd(PADAPTER padapter)
+{
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+	u8 u1H2CPsTuneParm[H2C_PSTUNEPARAM_LEN]={0};
+	u8 bcn_to_limit = 10; //10 * 100 * awakeinterval (ms)
+	u8 dtim_timeout = 5; //ms //wait broadcast data timer
+	u8 ps_timeout = 20;  //ms //Keep awake when tx
+	u8 dtim_period = 3; 
+
+_func_enter_;
+	//DBG_871X("%s(): FW LPS mode = %d\n", __func__, psmode);
+
+	SET_8703B_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(u1H2CPsTuneParm, bcn_to_limit);
+	SET_8703B_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(u1H2CPsTuneParm, dtim_timeout);
+	SET_8703B_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(u1H2CPsTuneParm, ps_timeout);
+	SET_8703B_H2CCMD_PSTUNE_PARM_ADOPT(u1H2CPsTuneParm, 1);
+	SET_8703B_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(u1H2CPsTuneParm, dtim_period);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPsTuneParm:", u1H2CPsTuneParm, H2C_PSTUNEPARAM_LEN);
+
+	FillH2CCmd8703B(padapter, H2C_8703B_PS_TUNING_PARA, H2C_PSTUNEPARAM_LEN, u1H2CPsTuneParm);
+_func_exit_;
+}
+
+void rtl8703b_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param)
+{
+	u8 u1H2CBtMpOperParm[H2C_BTMP_OPER_LEN] = {0};
+
+_func_enter_;
+
+	DBG_8192C("%s: idx=%d ver=%d reqnum=%d param1=0x%02x param2=0x%02x\n", __FUNCTION__, idx, ver, reqnum, param[0], param[1]);
+
+	SET_8703B_H2CCMD_BT_MPOPER_VER(u1H2CBtMpOperParm, ver);
+	SET_8703B_H2CCMD_BT_MPOPER_REQNUM(u1H2CBtMpOperParm, reqnum);
+	SET_8703B_H2CCMD_BT_MPOPER_IDX(u1H2CBtMpOperParm, idx);
+	SET_8703B_H2CCMD_BT_MPOPER_PARAM1(u1H2CBtMpOperParm, param[0]);
+	SET_8703B_H2CCMD_BT_MPOPER_PARAM2(u1H2CBtMpOperParm, param[1]);
+	SET_8703B_H2CCMD_BT_MPOPER_PARAM3(u1H2CBtMpOperParm, param[2]);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CBtMpOperParm:", u1H2CBtMpOperParm, H2C_BTMP_OPER_LEN);
+
+	FillH2CCmd8703B(padapter, H2C_8703B_BT_MP_OPER, H2C_BTMP_OPER_LEN, u1H2CBtMpOperParm);
+_func_exit_;
+}
+
+void rtl8703b_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param)
+{
+	//u8 cmd_param; //BIT0:enable, BIT1:NoConnect32k
+
+	DBG_871X("%s()\n", __func__);
+
+	FillH2CCmd8703B(padapter, H2C_8703B_FWLPS_IN_IPS_, 1, &cmd_param);
+
+}
+
+static s32 rtl8703b_set_FwLowPwrLps_cmd(PADAPTER padapter, u8 enable)
+{
+	//TODO
+	return _FALSE;	
+}
+
+
+void rtl8703b_download_rsvd_page(PADAPTER padapter, u8 mstatus)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+	BOOLEAN		bcn_valid = _FALSE;
+	u8	DLBcnCount=0;
+	u32 poll = 0;
+	u8 val8;
+
+_func_enter_;
+
+	DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d mstatus(%x)\n",
+		FUNC_ADPT_ARG(padapter), get_iface_type(padapter), mstatus);
+
+	if(mstatus == RT_MEDIA_CONNECT)
+	{
+		BOOLEAN bRecover = _FALSE;
+		u8 v8;
+
+		// We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
+		// Suggested by filen. Added by tynli.
+		rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
+
+		// set REG_CR bit 8
+		v8 = rtw_read8(padapter, REG_CR+1);
+		v8 |= BIT(0); // ENSWBCN
+		rtw_write8(padapter,  REG_CR+1, v8);
+
+		// Disable Hw protection for a time which revserd for Hw sending beacon.
+		// Fix download reserved page packet fail that access collision with the protection time.
+		// 2010.05.11. Added by tynli.
+		val8 = rtw_read8(padapter, REG_BCN_CTRL);
+		val8 &= ~EN_BCN_FUNCTION;
+		val8 |= DIS_TSF_UDT;
+		rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+		// Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
+		if (pHalData->RegFwHwTxQCtrl & BIT(6))
+			bRecover = _TRUE;
+
+		// To tell Hw the packet is not a real beacon frame.
+		rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl & ~BIT(6));
+		pHalData->RegFwHwTxQCtrl &= ~BIT(6);
+
+		// Clear beacon valid check bit.
+		rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
+		rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
+
+		DLBcnCount = 0;
+		poll = 0;
+		do
+		{
+			// download rsvd page.
+			rtw_hal_set_fw_rsvd_page(padapter, 0);
+			DLBcnCount++;
+			do
+			{
+				rtw_yield_os();
+				//rtw_mdelay_os(10);
+				// check rsvd page download OK.
+				rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid));
+				poll++;
+			} while (!bcn_valid && (poll%10) != 0 && !RTW_CANNOT_RUN(padapter));
+			
+		} while (!bcn_valid && DLBcnCount <= 100 && !RTW_CANNOT_RUN(padapter));
+
+		if (RTW_CANNOT_RUN(padapter))
+			;
+		else if(!bcn_valid)
+			DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",
+				ADPT_ARG(padapter) ,DLBcnCount, poll);
+		else {
+			struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+			pwrctl->fw_psmode_iface_id = padapter->iface_id;
+			DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",
+				ADPT_ARG(padapter), DLBcnCount, poll);
+		}
+
+		// 2010.05.11. Added by tynli.
+		val8 = rtw_read8(padapter, REG_BCN_CTRL);
+		val8 |= EN_BCN_FUNCTION;
+		val8 &= ~DIS_TSF_UDT;
+		rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+		// To make sure that if there exists an adapter which would like to send beacon.
+		// If exists, the origianl value of 0x422[6] will be 1, we should check this to
+		// prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
+		// the beacon cannot be sent by HW.
+		// 2010.06.23. Added by tynli.
+		if(bRecover)
+		{
+			rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl | BIT(6));
+			pHalData->RegFwHwTxQCtrl |= BIT(6);
+		}
+
+		// Clear CR[8] or beacon packet will not be send to TxBuf anymore.
+#ifndef CONFIG_PCI_HCI
+		v8 = rtw_read8(padapter, REG_CR+1);
+		v8 &= ~BIT(0); // ~ENSWBCN
+		rtw_write8(padapter, REG_CR+1, v8);
+#endif
+	}
+
+_func_exit_;
+}
+
+void rtl8703b_set_rssi_cmd(_adapter*padapter, u8 *param)
+{
+	rtl8703b_set_FwRssiSetting_cmd(padapter, param);
+}
+
+void rtl8703b_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus)
+{
+	struct sta_info *psta = NULL;
+	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
+	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
+
+	if(mstatus == 1)
+		rtl8703b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
+}
+
+//arg[0] = macid
+//arg[1] = raid
+//arg[2] = shortGIrate
+//arg[3] = init_rate
+void rtl8703b_Add_RateATid(PADAPTER pAdapter, u64 rate_bitmap, u8 *arg, u8 rssi_level)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	struct mlme_ext_priv	*pmlmeext = &pAdapter->mlmeextpriv;
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct sta_info	*psta;
+	u8 mac_id = arg[0];
+	u8 raid = arg[1];
+	u8 shortGI = arg[2];
+	u8 bw;
+	u32 bitmap = (u32) rate_bitmap;
+	u32 mask = bitmap&0x0FFFFFFF;
+
+	psta = pmlmeinfo->FW_sta_info[mac_id].psta;
+	if(psta == NULL)
+	{
+		return;
+	}
+
+	bw = psta->bw_mode;
+
+	if(rssi_level != DM_RATR_STA_INIT)
+		mask = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, mac_id, mask, rssi_level);		
+
+	DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask);
+	rtl8703b_set_FwMacIdConfig_cmd(pAdapter, mac_id, raid, bw, shortGI, mask);
+}
+
+#if 0
+void rtl8703b_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack)
+{
+	rtl8703b_set_FwAPReqRPT_cmd(padapter, need_ack);
+}
+#endif
+
+#ifdef CONFIG_BT_COEXIST
+static void ConstructBtNullFunctionData(
+	PADAPTER padapter,
+	u8 *pframe,
+	u32 *pLength,
+	u8 *StaAddr,
+	u8 bQoS,
+	u8 AC,
+	u8 bEosp,
+	u8 bForcePowerSave)
+{
+	struct rtw_ieee80211_hdr *pwlanhdr;
+	u16 *fctrl;
+	u32 pktlen;
+	struct mlme_ext_priv *pmlmeext;
+	struct mlme_ext_info *pmlmeinfo;
+	u8 bssid[ETH_ALEN];
+
+
+	DBG_871X("+" FUNC_ADPT_FMT ": qos=%d eosp=%d ps=%d\n",
+		FUNC_ADPT_ARG(padapter), bQoS, bEosp, bForcePowerSave);
+
+	pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
+	pmlmeext = &padapter->mlmeextpriv;
+	pmlmeinfo = &pmlmeext->mlmext_info;
+
+	if (NULL == StaAddr)
+	{
+		_rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
+		StaAddr = bssid;
+	}
+
+	fctrl = &pwlanhdr->frame_ctl;
+	*fctrl = 0;
+	if (bForcePowerSave)
+		SetPwrMgt(fctrl);
+
+	SetFrDs(fctrl);
+	_rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+
+	SetDuration(pwlanhdr, 0);
+	SetSeqNum(pwlanhdr, 0);
+
+	if (bQoS == _TRUE)
+	{
+		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
+
+		SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
+
+		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
+		SetPriority(&pwlanqoshdr->qc, AC);
+		SetEOSP(&pwlanqoshdr->qc, bEosp);
+
+		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
+	}
+	else
+	{
+		SetFrameSubType(pframe, WIFI_DATA_NULL);
+
+		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+	}
+
+	*pLength = pktlen;
+}
+
+static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	struct xmit_frame *pcmdframe;	
+	struct pkt_attrib *pattrib;
+	struct xmit_priv *pxmitpriv;
+	struct mlme_ext_priv *pmlmeext;
+	struct mlme_ext_info *pmlmeinfo;
+	u32	BeaconLength = 0;
+	u32	BTQosNullLength = 0;
+	u8 *ReservedPagePacket;
+	u8 TxDescLen, TxDescOffset;
+	u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;
+	u16	BufIndex, PageSize;
+	u32	TotalPacketLen, MaxRsvdPageBufSize=0;
+	RSVDPAGE_LOC RsvdPageLoc;
+
+
+//	DBG_8192C("+" FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
+
+	pHalData = GET_HAL_DATA(padapter);
+	pxmitpriv = &padapter->xmitpriv;
+	pmlmeext = &padapter->mlmeextpriv;
+	pmlmeinfo = &pmlmeext->mlmext_info;
+	TxDescLen = TXDESC_SIZE;
+	TxDescOffset = TXDESC_OFFSET;
+	PageSize = PAGE_SIZE_TX_8703B;
+
+	RsvdPageNum = BCNQ_PAGE_NUM_8703B;
+	MaxRsvdPageBufSize = RsvdPageNum*PageSize;
+
+	pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
+	if (pcmdframe == NULL) {
+		DBG_8192C("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
+		return;
+	}
+
+	ReservedPagePacket = pcmdframe->buf_addr;
+	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
+
+	//3 (1) beacon
+	BufIndex = TxDescOffset;
+	ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);
+
+	// When we count the first page size, we need to reserve description size for the RSVD
+	// packet, it will be filled in front of the packet in TXPKTBUF.
+	CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);
+	//If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
+	if (CurtPktPageNum == 1)
+	{
+		CurtPktPageNum += 1;
+	}
+	TotalPageNum += CurtPktPageNum;
+
+	BufIndex += (CurtPktPageNum*PageSize);
+
+	// Jump to lastest page
+	if (BufIndex < (MaxRsvdPageBufSize - PageSize))
+	{
+		BufIndex = TxDescOffset + (MaxRsvdPageBufSize - PageSize);
+		TotalPageNum = BCNQ_PAGE_NUM_8703B - 1;
+	}
+
+	//3 (6) BT Qos null data
+	RsvdPageLoc.LocBTQosNull = TotalPageNum;
+	ConstructBtNullFunctionData(
+		padapter,
+		&ReservedPagePacket[BufIndex],
+		&BTQosNullLength,
+		NULL,
+		_TRUE, 0, 0, _FALSE);
+	rtl8703b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);
+
+	CurtPktPageNum = (u8)PageNum_128(TxDescLen + BTQosNullLength);
+
+	TotalPageNum += CurtPktPageNum;
+
+	TotalPacketLen = BufIndex + BTQosNullLength;
+	if (TotalPacketLen > MaxRsvdPageBufSize)
+	{
+		DBG_8192C(FUNC_ADPT_FMT ": ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
+			FUNC_ADPT_ARG(padapter), TotalPacketLen, MaxRsvdPageBufSize);
+		goto error;
+	}
+
+	// update attribute
+	pattrib = &pcmdframe->attrib;
+	update_mgntframe_attrib(padapter, pattrib);
+	pattrib->qsel = QSLT_BEACON;
+	pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
+#ifdef CONFIG_PCI_HCI
+	dump_mgntframe(padapter, pcmdframe);
+#else
+	dump_mgntframe_and_wait(padapter, pcmdframe, 100);
+#endif
+
+//	DBG_8192C(FUNC_ADPT_FMT ": Set RSVD page location to Fw, TotalPacketLen(%d), TotalPageNum(%d)\n",
+//		FUNC_ADPT_ARG(padapter), TotalPacketLen, TotalPageNum);
+	rtl8703b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);
+	rtl8703b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);
+
+	return;
+
+error:
+	rtw_free_xmitframe(pxmitpriv, pcmdframe);
+}
+
+void rtl8703b_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	struct mlme_ext_priv *pmlmeext;
+	struct mlme_ext_info *pmlmeinfo;
+	u8 bRecover = _FALSE;
+	u8 bcn_valid = _FALSE;
+	u8 DLBcnCount = 0;
+	u32 poll = 0;
+	u8 val8;
+
+
+	DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d fw_state=0x%08X\n",
+		FUNC_ADPT_ARG(padapter), get_iface_type(padapter), get_fwstate(&padapter->mlmepriv));
+
+#ifdef CONFIG_DEBUG
+	if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _FALSE)
+	{
+		DBG_8192C(FUNC_ADPT_FMT ": [WARNING] not in AP mode!!\n",
+			FUNC_ADPT_ARG(padapter));
+	}
+#endif // CONFIG_DEBUG
+
+	pHalData = GET_HAL_DATA(padapter);
+	pmlmeext = &padapter->mlmeextpriv;
+	pmlmeinfo = &pmlmeext->mlmext_info;
+
+	// We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
+	// Suggested by filen. Added by tynli.
+	rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
+	
+	// set REG_CR bit 8
+	val8 = rtw_read8(padapter, REG_CR+1);
+	val8 |= BIT(0); // ENSWBCN
+	rtw_write8(padapter,  REG_CR+1, val8);
+	
+	// Disable Hw protection for a time which revserd for Hw sending beacon.
+	// Fix download reserved page packet fail that access collision with the protection time.
+	// 2010.05.11. Added by tynli.
+	val8 = rtw_read8(padapter, REG_BCN_CTRL);
+	val8 &= ~EN_BCN_FUNCTION;
+	val8 |= DIS_TSF_UDT;
+	rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+	// Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
+	if (pHalData->RegFwHwTxQCtrl & BIT(6))
+		bRecover = _TRUE;
+
+	// To tell Hw the packet is not a real beacon frame.
+	pHalData->RegFwHwTxQCtrl &= ~BIT(6);
+	rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
+
+	// Clear beacon valid check bit.
+	rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
+	rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
+
+	DLBcnCount = 0;
+	poll = 0;
+	do {
+		SetFwRsvdPagePkt_BTCoex(padapter);
+		DLBcnCount++;
+		do {
+			rtw_yield_os();
+//			rtw_mdelay_os(10);
+			// check rsvd page download OK.
+			rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, &bcn_valid);
+			poll++;
+		} while (!bcn_valid && (poll%10) != 0 && !RTW_CANNOT_RUN(padapter));
+	} while (!bcn_valid && (DLBcnCount <= 100) && !RTW_CANNOT_RUN(padapter));
+
+	if (_TRUE == bcn_valid)
+	{
+		struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+		pwrctl->fw_psmode_iface_id = padapter->iface_id;
+		DBG_8192C(ADPT_FMT": DL RSVD page success! DLBcnCount:%d, poll:%d\n",
+			ADPT_ARG(padapter), DLBcnCount, poll);
+	}
+	else
+	{
+		DBG_8192C(ADPT_FMT": DL RSVD page fail! DLBcnCount:%d, poll:%d\n",
+			ADPT_ARG(padapter), DLBcnCount, poll);
+		DBG_8192C(ADPT_FMT": DL RSVD page fail! bSurpriseRemoved=%s\n",
+			ADPT_ARG(padapter), rtw_is_surprise_removed(padapter)?"True":"False");
+		DBG_8192C(ADPT_FMT": DL RSVD page fail! bDriverStopped=%s\n",
+			ADPT_ARG(padapter), rtw_is_drv_stopped(padapter)?"True":"False");
+	}
+
+	// 2010.05.11. Added by tynli.
+	val8 = rtw_read8(padapter, REG_BCN_CTRL);
+	val8 |= EN_BCN_FUNCTION;
+	val8 &= ~DIS_TSF_UDT;
+	rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+	// To make sure that if there exists an adapter which would like to send beacon.
+	// If exists, the origianl value of 0x422[6] will be 1, we should check this to
+	// prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
+	// the beacon cannot be sent by HW.
+	// 2010.06.23. Added by tynli.
+	if (bRecover)
+	{
+		pHalData->RegFwHwTxQCtrl |= BIT(6);
+		rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
+	}
+
+	// Clear CR[8] or beacon packet will not be send to TxBuf anymore.
+#ifndef CONFIG_PCI_HCI
+	val8 = rtw_read8(padapter, REG_CR+1);
+	val8 &= ~BIT(0); // ~ENSWBCN
+	rtw_write8(padapter, REG_CR+1, val8);
+#endif
+}
+#endif // CONFIG_BT_COEXIST
+
+#ifdef CONFIG_P2P
+void rtl8703b_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	struct pwrctrl_priv		*pwrpriv = adapter_to_pwrctl(padapter);
+	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo );
+	struct P2P_PS_Offload_t	*p2p_ps_offload = (struct P2P_PS_Offload_t	*)(&pHalData->p2p_ps_offload);
+	u8	i;
+
+_func_enter_;
+
+#if 1
+	switch(p2p_ps_state)
+	{
+		case P2P_PS_DISABLE:
+			DBG_8192C("P2P_PS_DISABLE \n");
+			_rtw_memset(p2p_ps_offload, 0 ,1);
+			break;
+		case P2P_PS_ENABLE:
+			DBG_8192C("P2P_PS_ENABLE \n");
+			// update CTWindow value.
+			if( pwdinfo->ctwindow > 0 )
+			{
+				p2p_ps_offload->CTWindow_En = 1;
+				rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);
+			}
+
+			// hw only support 2 set of NoA
+			for( i=0 ; i<pwdinfo->noa_num ; i++)
+			{
+				// To control the register setting for which NOA
+				rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));
+				if(i == 0)
+					p2p_ps_offload->NoA0_En = 1;
+				else
+					p2p_ps_offload->NoA1_En = 1;
+
+				// config P2P NoA Descriptor Register
+				//DBG_8192C("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]);
+				rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
+
+				//DBG_8192C("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]);
+				rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
+
+				//DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]);
+				rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
+
+				//DBG_8192C("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]);
+				rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
+			}
+
+			if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) )
+			{
+				// rst p2p circuit
+				rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));
+
+				p2p_ps_offload->Offload_En = 1;
+
+				if(pwdinfo->role == P2P_ROLE_GO)
+				{
+					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:
+			DBG_8192C("P2P_PS_SCAN \n");
+			p2p_ps_offload->discovery = 1;
+			break;
+		case P2P_PS_SCAN_DONE:
+			DBG_8192C("P2P_PS_SCAN_DONE \n");
+			p2p_ps_offload->discovery = 0;
+			pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
+			break;
+		default:
+			break;
+	}
+
+	FillH2CCmd8703B(padapter, H2C_8703B_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
+#endif
+
+_func_exit_;
+
+}
+#endif //CONFIG_P2P
+
+
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+/*
+	ask FW to Reset sync register at Beacon early interrupt
+*/
+u8 rtl8703b_reset_tsf(_adapter *padapter, u8 reset_port )
+{
+	u8	buf[2];
+	u8	res=_SUCCESS;
+
+_func_enter_;
+	if (IFACE_PORT0==reset_port) {
+		buf[0] = 0x1; buf[1] = 0;
+
+	} else{
+		buf[0] = 0x0; buf[1] = 0x1;
+	}
+	FillH2CCmd8703B(padapter, H2C_8703B_RESET_TSF, 2, buf);
+_func_exit_;
+
+	return res;
+}
+#endif	// CONFIG_TSF_RESET_OFFLOAD
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_dm.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_dm.c
new file mode 100644
index 000000000..b8100fece
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_dm.c
@@ -0,0 +1,565 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *
+ ******************************************************************************/
+//============================================================
+// Description:
+//
+// This file is for 92CE/92CU dynamic mechanism only
+//
+//
+//============================================================
+#define _RTL8703B_DM_C_
+
+//============================================================
+// include files
+//============================================================
+#include <rtl8703b_hal.h>
+
+//============================================================
+// Global var
+//============================================================
+
+
+static VOID
+dm_CheckProtection(
+	IN	PADAPTER	Adapter
+	)
+{
+#if 0
+	PMGNT_INFO		pMgntInfo = &(Adapter->MgntInfo);
+	u1Byte			CurRate, RateThreshold;
+
+	if(pMgntInfo->pHTInfo->bCurBW40MHz)
+		RateThreshold = MGN_MCS1;
+	else
+		RateThreshold = MGN_MCS3;
+
+	if(Adapter->TxStats.CurrentInitTxRate <= RateThreshold)
+	{
+		pMgntInfo->bDmDisableProtect = TRUE;
+		DbgPrint("Forced disable protect: %x\n", Adapter->TxStats.CurrentInitTxRate);
+	}
+	else
+	{
+		pMgntInfo->bDmDisableProtect = FALSE;
+		DbgPrint("Enable protect: %x\n", Adapter->TxStats.CurrentInitTxRate);
+	}
+#endif
+}
+
+static VOID
+dm_CheckStatistics(
+	IN	PADAPTER	Adapter
+	)
+{
+#if 0
+	if(!Adapter->MgntInfo.bMediaConnect)
+		return;
+
+	//2008.12.10 tynli Add for getting Current_Tx_Rate_Reg flexibly.
+	rtw_hal_get_hwreg( Adapter, HW_VAR_INIT_TX_RATE, (pu1Byte)(&Adapter->TxStats.CurrentInitTxRate) );
+
+	// Calculate current Tx Rate(Successful transmited!!)
+
+	// Calculate current Rx Rate(Successful received!!)
+
+	//for tx tx retry count
+	rtw_hal_get_hwreg( Adapter, HW_VAR_RETRY_COUNT, (pu1Byte)(&Adapter->TxStats.NumTxRetryCount) );
+#endif
+}
+#ifdef CONFIG_SUPPORT_HW_WPS_PBC
+static void dm_CheckPbcGPIO(_adapter *padapter)
+{
+	u8	tmp1byte;
+	u8	bPbcPressed = _FALSE;
+
+	if(!padapter->registrypriv.hw_wps_pbc)
+		return;
+
+#ifdef CONFIG_USB_HCI
+	tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
+	tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT);
+	rtw_write8(padapter, GPIO_IO_SEL, tmp1byte);	//enable GPIO[2] as output mode
+
+	tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
+	rtw_write8(padapter,  GPIO_IN, tmp1byte);		//reset the floating voltage level
+
+	tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
+	tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
+	rtw_write8(padapter, GPIO_IO_SEL, tmp1byte);	//enable GPIO[2] as input mode
+
+	tmp1byte =rtw_read8(padapter, GPIO_IN);
+
+	if (tmp1byte == 0xff)
+		return ;
+
+	if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)
+	{
+		bPbcPressed = _TRUE;
+	}
+#else
+	tmp1byte = rtw_read8(padapter, GPIO_IN);
+	//RT_TRACE(COMP_IO, DBG_TRACE, ("dm_CheckPbcGPIO - %x\n", tmp1byte));
+
+	if (tmp1byte == 0xff || padapter->init_adpt_in_progress)
+		return ;
+
+	if((tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)==0)
+	{
+		bPbcPressed = _TRUE;
+	}
+#endif
+
+	if( _TRUE == bPbcPressed)
+	{
+		// Here we only set bPbcPressed to true
+		// After trigger PBC, the variable will be set to false
+		DBG_8192C("CheckPbcGPIO - PBC is pressed\n");
+		rtw_request_wps_pbc_event(padapter);
+	}
+}
+#endif //#ifdef CONFIG_SUPPORT_HW_WPS_PBC
+
+
+#ifdef CONFIG_PCI_HCI
+//
+//	Description:
+//		Perform interrupt migration dynamically to reduce CPU utilization.
+//
+//	Assumption:
+//		1. Do not enable migration under WIFI test.
+//
+//	Created by Roger, 2010.03.05.
+//
+VOID
+dm_InterruptMigration(
+	IN	PADAPTER	Adapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	struct mlme_priv	*pmlmepriv = &(Adapter->mlmepriv);
+	BOOLEAN			bCurrentIntMt, bCurrentACIntDisable;
+	BOOLEAN			IntMtToSet = _FALSE;
+	BOOLEAN			ACIntToSet = _FALSE;
+
+
+	// Retrieve current interrupt migration and Tx four ACs IMR settings first.
+	bCurrentIntMt = pHalData->bInterruptMigration;
+	bCurrentACIntDisable = pHalData->bDisableTxInt;
+
+	//
+	// <Roger_Notes> Currently we use busy traffic for reference instead of RxIntOK counts to prevent non-linear Rx statistics
+	// when interrupt migration is set before. 2010.03.05.
+	//
+	if(!Adapter->registrypriv.wifi_spec &&
+		(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) &&
+		pmlmepriv->LinkDetectInfo.bHigherBusyTraffic)
+	{
+		IntMtToSet = _TRUE;
+
+		// To check whether we should disable Tx interrupt or not.
+		if(pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic )
+			ACIntToSet = _TRUE;
+	}
+
+	//Update current settings.
+	if( bCurrentIntMt != IntMtToSet ){
+		DBG_8192C("%s(): Update interrrupt migration(%d)\n",__FUNCTION__,IntMtToSet);
+		if(IntMtToSet)
+		{
+			//
+			// <Roger_Notes> Set interrrupt migration timer and corresponging Tx/Rx counter.
+			// timer 25ns*0xfa0=100us for 0xf packets.
+			// 2010.03.05.
+			//
+			rtw_write32(Adapter, REG_INT_MIG, 0xff000fa0);// 0x306:Rx, 0x307:Tx
+			pHalData->bInterruptMigration = IntMtToSet;
+		}
+		else
+		{
+			// Reset all interrupt migration settings.
+			rtw_write32(Adapter, REG_INT_MIG, 0);
+			pHalData->bInterruptMigration = IntMtToSet;
+		}
+	}
+
+	/*if( bCurrentACIntDisable != ACIntToSet ){
+		DBG_8192C("%s(): Update AC interrrupt(%d)\n",__FUNCTION__,ACIntToSet);
+		if(ACIntToSet) // Disable four ACs interrupts.
+		{
+			//
+			// <Roger_Notes> Disable VO, VI, BE and BK four AC interrupts to gain more efficient CPU utilization.
+			// When extremely highly Rx OK occurs, we will disable Tx interrupts.
+			// 2010.03.05.
+			//
+			UpdateInterruptMask8192CE( Adapter, 0, RT_AC_INT_MASKS );
+			pHalData->bDisableTxInt = ACIntToSet;
+		}
+		else// Enable four ACs interrupts.
+		{
+			UpdateInterruptMask8192CE( Adapter, RT_AC_INT_MASKS, 0 );
+			pHalData->bDisableTxInt = ACIntToSet;
+		}
+	}*/
+
+}
+
+#endif
+
+//
+// Initialize GPIO setting registers
+//
+static void
+dm_InitGPIOSetting(
+	IN	PADAPTER	Adapter
+	)
+{
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(Adapter);
+
+	u8	tmp1byte;
+
+	tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
+	tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
+
+	rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
+}
+//============================================================
+// functions
+//============================================================
+static void Init_ODM_ComInfo_8703b(PADAPTER	Adapter)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+	u32 SupportAbility = 0;
+	u8	cut_ver,fab_ver;
+
+	Init_ODM_ComInfo(Adapter);
+
+	ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PACKAGE_TYPE, pHalData->PackageType);
+
+	fab_ver = ODM_TSMC;
+	cut_ver = GET_CVID_CUT_VERSION(pHalData->VersionID);
+
+	DBG_871X("%s(): fab_ver=%d cut_ver=%d\n", __func__, fab_ver, cut_ver);
+	ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_FAB_VER,fab_ver);
+	ODM_CmnInfoInit(pDM_Odm,ODM_CMNINFO_CUT_VER,cut_ver);
+
+	#ifdef CONFIG_DISABLE_ODM
+	SupportAbility = 0;
+	#else
+	SupportAbility = 	
+#if 1	
+					ODM_RF_CALIBRATION |
+					ODM_RF_TX_PWR_TRACK	
+#else
+					0
+#endif
+							;	
+	/*if(pHalData->AntDivCfg)
+		SupportAbility |= ODM_BB_ANT_DIV;*/
+	#endif	
+
+	ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_ABILITY,SupportAbility);
+}
+
+static void Update_ODM_ComInfo_8703b(PADAPTER	Adapter)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+	u32 SupportAbility = 0;
+
+	SupportAbility = 0
+		| ODM_BB_DIG 					/* For BB */
+		| ODM_BB_RA_MASK		
+		| ODM_BB_FA_CNT			
+		| ODM_BB_RSSI_MONITOR
+		| ODM_BB_CCK_PD		
+		| ODM_BB_CFO_TRACKING	
+		/* | ODM_BB_PWR_TRAIN */	
+		| ODM_BB_NHM_CNT	
+		 | ODM_RF_TX_PWR_TRACK	/* For RF */
+		 | ODM_RF_CALIBRATION 
+		| ODM_MAC_EDCA_TURBO		/* For MAC */
+		;
+
+	if (rtw_odm_adaptivity_needed(Adapter) == _TRUE) {
+		rtw_odm_adaptivity_config_msg(RTW_DBGDUMP, Adapter);
+		SupportAbility |= ODM_BB_ADAPTIVITY;
+	}
+
+#ifdef CONFIG_ANTENNA_DIVERSITY
+	if(pHalData->AntDivCfg)
+		SupportAbility |= ODM_BB_ANT_DIV;
+#endif
+
+#if (MP_DRIVER==1)
+	if (Adapter->registrypriv.mp_mode == 1) {
+		SupportAbility = 0
+			| ODM_RF_CALIBRATION
+			| ODM_RF_TX_PWR_TRACK
+			;
+	}
+#endif//(MP_DRIVER==1)
+
+#ifdef CONFIG_DISABLE_ODM
+	SupportAbility = 0;
+#endif//CONFIG_DISABLE_ODM
+
+	ODM_CmnInfoUpdate(pDM_Odm,ODM_CMNINFO_ABILITY,SupportAbility);
+}
+
+void
+rtl8703b_InitHalDm(
+	IN	PADAPTER	Adapter
+	)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+
+	u8	i;
+
+#ifdef CONFIG_USB_HCI
+	dm_InitGPIOSetting(Adapter);
+#endif
+
+	pHalData->DM_Type = DM_Type_ByDriver;
+
+	Update_ODM_ComInfo_8703b(Adapter);
+
+	ODM_DMInit(pDM_Odm);
+
+}
+
+VOID
+rtl8703b_HalDmWatchDog(
+	IN	PADAPTER	Adapter
+	)
+{
+	BOOLEAN		bFwCurrentInPSMode = _FALSE;
+	BOOLEAN		bFwPSAwake = _TRUE;
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+#ifdef CONFIG_CONCURRENT_MODE
+	PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
+#endif //CONFIG_CONCURRENT_MODE
+
+//#if MP_DRIVER
+if (Adapter->registrypriv.mp_mode == 1 && Adapter->mppriv.mp_dm ==0) // for MP power tracking
+	return;
+//#endif
+
+	if (!rtw_is_hw_init_completed(Adapter))
+		goto skip_dm;
+
+#ifdef CONFIG_LPS
+	bFwCurrentInPSMode = adapter_to_pwrctl(Adapter)->bFwCurrentInPSMode;
+	rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake));
+#endif
+
+#ifdef CONFIG_P2P
+	// Fw is under p2p powersaving mode, driver should stop dynamic mechanism.
+	// modifed by thomas. 2011.06.11.
+	if(Adapter->wdinfo.p2p_ps_mode)
+		bFwPSAwake = _FALSE;
+#endif //CONFIG_P2P
+
+
+	if ((rtw_is_hw_init_completed(Adapter))
+		&& ((!bFwCurrentInPSMode) && bFwPSAwake)) {
+		//
+		// Calculate Tx/Rx statistics.
+		//
+		dm_CheckStatistics(Adapter);
+		rtw_hal_check_rxfifo_full(Adapter);
+		//
+		// Dynamically switch RTS/CTS protection.
+		//
+		//dm_CheckProtection(Adapter);
+
+#ifdef CONFIG_PCI_HCI
+		// 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput.
+		// Tx Migration settings.
+		//dm_InterruptMigration(Adapter);
+
+		//if(Adapter->HalFunc.TxCheckStuckHandler(Adapter))
+		//	PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem));
+#endif
+	}
+
+	//ODM
+	if (rtw_is_hw_init_completed(Adapter))
+	{
+		u8	bLinked=_FALSE;
+		u8	bsta_state=_FALSE;
+		u8	bBtDisabled = _TRUE;
+
+		if(rtw_linked_check(Adapter)){			
+			bLinked = _TRUE;
+			if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE))
+				bsta_state = _TRUE;
+		}
+			
+#ifdef CONFIG_CONCURRENT_MODE
+		if(pbuddy_adapter && rtw_linked_check(pbuddy_adapter)){
+			bLinked = _TRUE;
+			if(pbuddy_adapter && check_fwstate(&pbuddy_adapter->mlmepriv, WIFI_STATION_STATE))
+				bsta_state = _TRUE;
+		}
+#endif //CONFIG_CONCURRENT_MODE
+
+		ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked);
+		ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_STATION_STATE, bsta_state);
+
+		//ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM);
+
+#ifdef CONFIG_BT_COEXIST
+		bBtDisabled = rtw_btcoex_IsBtDisabled(Adapter);
+#endif // CONFIG_BT_COEXIST
+		ODM_CmnInfoUpdate(&pHalData->odmpriv, ODM_CMNINFO_BT_ENABLED, ((bBtDisabled == _TRUE)?_FALSE:_TRUE));
+
+		ODM_DMWatchdog(&pHalData->odmpriv);
+	}
+
+skip_dm:
+
+	// Check GPIO to determine current RF on/off and Pbc status.
+	// Check Hardware Radio ON/OFF or not
+	//if(Adapter->MgntInfo.PowerSaveControl.bGpioRfSw)
+	//{
+		//RTPRINT(FPWR, PWRHW, ("dm_CheckRfCtrlGPIO \n"));
+	//	dm_CheckRfCtrlGPIO(Adapter);
+	//}
+#ifdef CONFIG_SUPPORT_HW_WPS_PBC
+	dm_CheckPbcGPIO(Adapter);
+#endif
+	return;
+}
+
+void rtl8703b_hal_dm_in_lps(PADAPTER padapter)
+{
+	u32	PWDB_rssi=0;	
+	struct mlme_priv 	*pmlmepriv = &padapter->mlmepriv;
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
+	pDIG_T	pDM_DigTable = &pDM_Odm->DM_DigTable;
+	struct sta_priv *pstapriv = &padapter->stapriv;
+	struct sta_info *psta = NULL;
+
+	DBG_871X("%s, RSSI_Min=%d\n", __func__, pDM_Odm->RSSI_Min);
+
+	//update IGI
+	ODM_Write_DIG(pDM_Odm, pDM_Odm->RSSI_Min);
+
+
+	//set rssi to fw
+	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+	if(psta && (psta->rssi_stat.UndecoratedSmoothedPWDB > 0))
+	{
+		PWDB_rssi = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16) );
+		
+		rtl8703b_set_rssi_cmd(padapter, (u8*)&PWDB_rssi);
+	}	
+
+}
+
+void rtl8703b_HalDmWatchDog_in_LPS(IN	PADAPTER	Adapter)
+{
+	u8	bLinked=_FALSE;
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	struct mlme_priv 	*pmlmepriv = &Adapter->mlmepriv;
+	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
+	pDIG_T	pDM_DigTable = &pDM_Odm->DM_DigTable;
+	struct sta_priv *pstapriv = &Adapter->stapriv;
+	struct sta_info *psta = NULL;
+#ifdef CONFIG_CONCURRENT_MODE
+	PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
+#endif //CONFIG_CONCURRENT_MODE
+
+	if (!rtw_is_hw_init_completed(Adapter))
+		goto skip_lps_dm;
+
+
+	if(rtw_linked_check(Adapter))
+		bLinked = _TRUE;
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (pbuddy_adapter && rtw_linked_check(pbuddy_adapter))
+		bLinked = _TRUE;
+#endif //CONFIG_CONCURRENT_MODE
+
+	ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked);
+
+	if(bLinked == _FALSE)
+		goto skip_lps_dm;
+
+	if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR))
+		goto skip_lps_dm;
+
+
+	//ODM_DMWatchdog(&pHalData->odmpriv);	
+	//Do DIG by RSSI In LPS-32K 
+	
+      //.1 Find MIN-RSSI
+	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+	if(psta == NULL)
+		goto skip_lps_dm;
+
+	pHalData->EntryMinUndecoratedSmoothedPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
+
+	DBG_871X("CurIGValue=%d, EntryMinUndecoratedSmoothedPWDB = %d\n", pDM_DigTable->CurIGValue, pHalData->EntryMinUndecoratedSmoothedPWDB );
+
+	if(pHalData->EntryMinUndecoratedSmoothedPWDB <=0)
+		goto skip_lps_dm;
+
+	pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB;
+
+	pDM_Odm->RSSI_Min = pHalData->MinUndecoratedPWDBForDM;
+
+	//if(pDM_DigTable->CurIGValue != pDM_Odm->RSSI_Min)
+	if((pDM_DigTable->CurIGValue > pDM_Odm->RSSI_Min + 5) || 
+             (pDM_DigTable->CurIGValue < pDM_Odm->RSSI_Min - 5))
+
+	{		
+#ifdef CONFIG_LPS
+		rtw_dm_in_lps_wk_cmd(Adapter);		
+#endif /* CONFIG_LPS */
+	}
+	
+	
+skip_lps_dm:
+
+	return;
+
+}
+
+void rtl8703b_init_dm_priv(IN PADAPTER Adapter)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T 		podmpriv = &pHalData->odmpriv;
+	Init_ODM_ComInfo_8703b(Adapter);
+	ODM_InitAllTimers(podmpriv );
+}
+
+void rtl8703b_deinit_dm_priv(IN PADAPTER Adapter)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T 		podmpriv = &pHalData->odmpriv;
+	ODM_CancelAllTimers(podmpriv);
+
+}
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_hal_init.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_hal_init.c
new file mode 100644
index 000000000..4f140c626
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_hal_init.c
@@ -0,0 +1,7377 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#define _HAL_INIT_C_
+
+#include <rtl8703b_hal.h>
+#include "hal_com_h2c.h"
+#include <hal_com.h>
+
+#define FW_DOWNLOAD_SIZE_8703B 8192
+
+static VOID
+_FWDownloadEnable(
+	IN	PADAPTER		padapter,
+	IN	BOOLEAN			enable
+	)
+{
+	u8	tmp, count = 0;
+
+	if(enable)
+	{
+		// 8051 enable
+		tmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+		rtw_write8(padapter, REG_SYS_FUNC_EN+1, tmp|0x04);
+
+		tmp = rtw_read8(padapter, REG_MCUFWDL);
+		rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
+
+		do{
+			tmp = rtw_read8(padapter, REG_MCUFWDL);
+			if(tmp & 0x01)
+				break;
+			rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
+			rtw_msleep_os(1);
+		}while(count++<100);
+		if(count > 0)
+			DBG_871X("%s: !!!!!!!!Write 0x80 Fail!: count = %d\n", __func__, count);
+
+		// 8051 reset
+		tmp = rtw_read8(padapter, REG_MCUFWDL+2);
+		rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
+	}
+	else
+	{
+		// MCU firmware download disable.
+		tmp = rtw_read8(padapter, REG_MCUFWDL);
+		rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
+	}
+}
+
+static int
+_BlockWrite(
+	IN		PADAPTER		padapter,
+	IN		PVOID		buffer,
+	IN		u32			buffSize
+	)
+{
+	int ret = _SUCCESS;
+
+	u32			blockSize_p1 = 4;	// (Default) Phase #1 : PCI muse use 4-byte write to download FW
+	u32			blockSize_p2 = 8;	// Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
+	u32			blockSize_p3 = 1;	// Phase #3 : Use 1-byte, the remnant of FW image.
+	u32			blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
+	u32			remainSize_p1 = 0, remainSize_p2 = 0;
+	u8			*bufferPtr	= (u8*)buffer;
+	u32			i=0, offset=0;
+#ifdef CONFIG_PCI_HCI
+	u8			remainFW[4] = {0, 0, 0, 0};
+	u8			*p = NULL;
+#endif
+
+#ifdef CONFIG_USB_HCI
+	blockSize_p1 = 254;
+#endif
+
+//	printk("====>%s %d\n", __func__, __LINE__);
+
+	//3 Phase #1
+	blockCount_p1 = buffSize / blockSize_p1;
+	remainSize_p1 = buffSize % blockSize_p1;
+
+	if (blockCount_p1) {
+		RT_TRACE(_module_hal_init_c_, _drv_notice_,
+				("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n",
+				buffSize, blockSize_p1, blockCount_p1, remainSize_p1));
+	}
+
+	for (i = 0; i < blockCount_p1; i++)
+	{
+#ifdef CONFIG_USB_HCI
+		ret = rtw_writeN(padapter, (FW_8703B_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
+#else
+		ret = rtw_write32(padapter, (FW_8703B_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32*)(bufferPtr + i * blockSize_p1))));
+#endif
+		if(ret == _FAIL) {
+			printk("====>%s %d i:%d\n", __func__, __LINE__, i);
+			goto exit;
+		}
+	}
+
+#ifdef CONFIG_PCI_HCI
+	p = (u8*)((u32*)(bufferPtr + blockCount_p1 * blockSize_p1));
+	if (remainSize_p1) {
+		switch (remainSize_p1) {
+		case 0:
+			break;
+		case 3:
+			remainFW[2]=*(p+2);
+		case 2: 	
+			remainFW[1]=*(p+1);
+		case 1: 	
+			remainFW[0]=*(p);
+			ret = rtw_write32(padapter, (FW_8703B_START_ADDRESS + blockCount_p1 * blockSize_p1), 
+				 le32_to_cpu(*(u32*)remainFW));	
+		}
+		return ret;
+	}
+#endif
+
+	//3 Phase #2
+	if (remainSize_p1)
+	{
+		offset = blockCount_p1 * blockSize_p1;
+
+		blockCount_p2 = remainSize_p1/blockSize_p2;
+		remainSize_p2 = remainSize_p1%blockSize_p2;
+
+		if (blockCount_p2) {
+				RT_TRACE(_module_hal_init_c_, _drv_notice_,
+						("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n",
+						(buffSize-offset), blockSize_p2 ,blockCount_p2, remainSize_p2));
+		}
+
+#ifdef CONFIG_USB_HCI
+		for (i = 0; i < blockCount_p2; i++) {
+			ret = rtw_writeN(padapter, (FW_8703B_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
+
+			if(ret == _FAIL)
+				goto exit;
+		}
+#endif
+	}
+
+	//3 Phase #3
+	if (remainSize_p2)
+	{
+		offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
+
+		blockCount_p3 = remainSize_p2 / blockSize_p3;
+
+		RT_TRACE(_module_hal_init_c_, _drv_notice_,
+				("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n",
+				(buffSize-offset), blockSize_p3, blockCount_p3));
+
+		for(i = 0 ; i < blockCount_p3 ; i++){
+			ret = rtw_write8(padapter, (FW_8703B_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
+
+			if(ret == _FAIL) {
+				printk("====>%s %d i:%d\n", __func__, __LINE__, i);
+				goto exit;
+			}
+		}
+	}
+exit:
+	return ret;
+}
+
+static int
+_PageWrite(
+	IN		PADAPTER	padapter,
+	IN		u32			page,
+	IN		PVOID		buffer,
+	IN		u32			size
+	)
+{
+	u8 value8;
+	u8 u8Page = (u8) (page & 0x07) ;
+
+	value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page ;
+	rtw_write8(padapter, REG_MCUFWDL+2,value8);
+
+	return _BlockWrite(padapter,buffer,size);
+}
+
+static VOID
+_FillDummy(
+	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 int
+_WriteFW(
+	IN		PADAPTER		padapter,
+	IN		PVOID			buffer,
+	IN		u32			size
+	)
+{
+	// Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
+	int ret = _SUCCESS;
+	u32 	pageNums,remainSize ;
+	u32 	page, offset;
+	u8		*bufferPtr = (u8*)buffer;
+
+#ifdef CONFIG_PCI_HCI
+	// 20100120 Joseph: Add for 88CE normal chip.
+	// Fill in zero to make firmware image to dword alignment.
+	_FillDummy(bufferPtr, &size);
+#endif
+
+	pageNums = size / MAX_DLFW_PAGE_SIZE ;
+	//RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4 \n"));
+	remainSize = size % MAX_DLFW_PAGE_SIZE;
+
+	for (page = 0; page < pageNums; page++) {
+		offset = page * MAX_DLFW_PAGE_SIZE;
+		ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_DLFW_PAGE_SIZE);
+
+		if(ret == _FAIL) {
+			printk("====>%s %d\n", __func__, __LINE__);
+			goto exit;
+		}
+	}
+	if (remainSize) {
+		offset = pageNums * MAX_DLFW_PAGE_SIZE;
+		page = pageNums;
+		ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
+
+		if(ret == _FAIL) {
+			printk("====>%s %d\n", __func__, __LINE__);
+			goto exit;
+		}
+	}
+	RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n"));
+
+exit:
+	return ret;
+}
+
+void _8051Reset8703(PADAPTER padapter)
+{
+	u8 cpu_rst;
+	u8 io_rst;
+
+#if 0
+	io_rst = rtw_read8(padapter, REG_RSV_CTRL);
+	rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1));
+#endif
+
+	// Reset 8051(WLMCU) IO wrapper
+	// 0x1c[8] = 0
+	// Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624
+	io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
+	io_rst &= ~BIT(0);
+	rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
+
+	cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+	cpu_rst &= ~BIT(2);
+	rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
+
+#if 0
+	io_rst = rtw_read8(padapter, REG_RSV_CTRL);
+	rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1));
+#endif
+
+	// Enable 8051 IO wrapper	
+	// 0x1c[8] = 1
+	io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
+	io_rst |= BIT(0);
+	rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
+
+	cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+	cpu_rst |= BIT(2);
+	rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
+
+	DBG_8192C("%s: Finish\n", __FUNCTION__);
+}
+
+static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
+{
+	s32 ret = _FAIL;
+	u32 value32;
+	u32 start = rtw_get_current_time();
+	u32 cnt = 0;
+
+	/* polling CheckSum report */
+	do {
+		cnt++;
+		value32 = rtw_read32(adapter, REG_MCUFWDL);
+		if (value32 & FWDL_ChkSum_rpt || RTW_CANNOT_IO(adapter))
+			break;
+		rtw_yield_os();
+	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
+
+	if (!(value32 & FWDL_ChkSum_rpt)) {
+		goto exit;
+	}
+
+	if (rtw_fwdl_test_trigger_chksum_fail())
+		goto exit;
+
+	ret = _SUCCESS;
+
+exit:
+	DBG_871X("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
+	, (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
+
+	return ret;
+}
+
+static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
+{
+	s32 ret = _FAIL;
+	u32	value32;
+	u32 start = rtw_get_current_time();
+	u32 cnt = 0;
+	u32 value_to_check = 0;
+	u32 value_expected = (MCUFWDL_RDY | FWDL_ChkSum_rpt | WINTINI_RDY | RAM_DL_SEL);
+
+	value32 = rtw_read32(adapter, REG_MCUFWDL);
+	value32 |= MCUFWDL_RDY;
+	value32 &= ~WINTINI_RDY;
+	rtw_write32(adapter, REG_MCUFWDL, value32);
+
+	_8051Reset8703(adapter);
+
+	/*  polling for FW ready */
+	do {
+		cnt++;
+		value32 = rtw_read32(adapter, REG_MCUFWDL);
+		value_to_check = value32 & value_expected;
+		if ((value_to_check == value_expected) || RTW_CANNOT_IO(adapter))
+			break;
+		rtw_yield_os();
+	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
+
+	if (value_to_check != value_expected) {
+		goto exit;
+	}
+
+	if (rtw_fwdl_test_trigger_wintint_rdy_fail())
+		goto exit;
+
+	ret = _SUCCESS;
+
+exit:
+	DBG_871X("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
+		, (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
+
+	return ret;
+}
+
+#define IS_FW_81xxC(padapter)	(((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
+
+void rtl8703b_FirmwareSelfReset(PADAPTER padapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u8	u1bTmp;
+	u8	Delay = 100;
+
+	if (!(IS_FW_81xxC(padapter) &&
+		  ((pHalData->FirmwareVersion < 0x21) ||
+		   (pHalData->FirmwareVersion == 0x21 &&
+		    pHalData->FirmwareSubVersion < 0x01)))) // after 88C Fw v33.1
+	{
+		//0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test
+		rtw_write8(padapter, REG_HMETFR+3, 0x20);
+
+		u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+		while (u1bTmp & BIT2)
+		{
+			Delay--;
+			if(Delay == 0)
+				break;
+			rtw_udelay_os(50);
+			u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+		}
+		RT_TRACE(_module_hal_init_c_, _drv_notice_, ("-%s: 8051 reset success (%d)\n", __FUNCTION__, Delay));
+
+		if (Delay == 0)
+		{
+			RT_TRACE(_module_hal_init_c_, _drv_notice_, ("%s: Force 8051 reset!!!\n", __FUNCTION__));
+			//force firmware reset
+			u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+			rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
+		}
+	}
+}
+
+#ifdef CONFIG_FILE_FWIMG
+extern char *rtw_fw_file_path;
+extern char *rtw_fw_wow_file_path;
+#ifdef CONFIG_MP_INCLUDED
+extern char *rtw_fw_mp_bt_file_path;
+#endif // CONFIG_MP_INCLUDED
+u8 FwBuffer[FW_8703B_SIZE];
+#endif // CONFIG_FILE_FWIMG
+
+#ifdef CONFIG_MP_INCLUDED
+int _WriteBTFWtoTxPktBuf8703B(
+	IN		PADAPTER		Adapter,
+	IN		PVOID			buffer,
+	IN		u4Byte			FwBufLen,
+	IN		u1Byte			times
+	)
+{
+	int			rtStatus = _SUCCESS;
+	//u4Byte				value32;
+	//u1Byte				numHQ, numLQ, numPubQ;//, txpktbuf_bndy;
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+	//PMGNT_INFO		pMgntInfo = &(Adapter->MgntInfo);
+	u1Byte				BcnValidReg;
+	u1Byte				count=0, DLBcnCount=0;
+	pu1Byte 			FwbufferPtr = (pu1Byte)buffer;
+	//PRT_TCB 			pTcb, ptempTcb;
+	//PRT_TX_LOCAL_BUFFER pBuf;
+	BOOLEAN 			bRecover=_FALSE;
+	pu1Byte 			ReservedPagePacket = NULL;
+	pu1Byte 			pGenBufReservedPagePacket = NULL;
+	u4Byte				TotalPktLen,txpktbuf_bndy;
+	//u1Byte				tmpReg422;
+	//u1Byte				u1bTmp;
+	u8 			*pframe;
+	struct xmit_priv	*pxmitpriv = &(Adapter->xmitpriv);
+	struct xmit_frame	*pmgntframe;
+	struct pkt_attrib	*pattrib;
+	u8 			txdesc_offset = TXDESC_OFFSET;
+	u8			val8;
+#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
+	u8			u1bTmp;
+#endif
+
+#if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
+	TotalPktLen = FwBufLen;
+#else
+	TotalPktLen = FwBufLen+pHalData->HWDescHeadLength;
+#endif
+
+	if((TotalPktLen+TXDESC_OFFSET) > MAX_CMDBUF_SZ)
+	{
+		DBG_871X(" WARNING %s => Total packet len = %d > MAX_CMDBUF_SZ:%d \n"
+			,__FUNCTION__,(TotalPktLen+TXDESC_OFFSET),MAX_CMDBUF_SZ);
+		return _FAIL;
+	}
+
+	pGenBufReservedPagePacket = rtw_zmalloc(TotalPktLen);//GetGenTempBuffer (Adapter, TotalPktLen);
+	if (!pGenBufReservedPagePacket)
+		return _FAIL;
+
+	ReservedPagePacket = (u1Byte *)pGenBufReservedPagePacket;
+
+	_rtw_memset(ReservedPagePacket, 0, TotalPktLen);
+
+#if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
+	_rtw_memcpy(ReservedPagePacket, FwbufferPtr, FwBufLen);
+
+#else
+	PlatformMoveMemory(ReservedPagePacket+Adapter->HWDescHeadLength , FwbufferPtr, FwBufLen);
+#endif
+
+	//---------------------------------------------------------
+	// 1. Pause BCN
+	//---------------------------------------------------------
+	//Set REG_CR bit 8. DMA beacon by SW.
+#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
+	u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR+1);
+	PlatformEFIOWrite1Byte(Adapter,  REG_CR+1, (u1bTmp|BIT0));
+#else
+	// Remove for temparaily because of the code on v2002 is not sync to MERGE_TMEP for USB/SDIO.
+	// De not remove this part on MERGE_TEMP. by tynli.
+	//pHalData->RegCR_1 |= (BIT0);
+	//PlatformEFIOWrite1Byte(Adapter,  REG_CR+1, pHalData->RegCR_1);
+#endif
+
+	// Disable Hw protection for a time which revserd for Hw sending beacon.
+	// Fix download reserved page packet fail that access collision with the protection time.
+	// 2010.05.11. Added by tynli.
+	val8 = rtw_read8(Adapter, REG_BCN_CTRL);
+	val8 &= ~EN_BCN_FUNCTION;
+	val8 |= DIS_TSF_UDT;
+	rtw_write8(Adapter, REG_BCN_CTRL, val8);
+
+#if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
+	tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL+2);
+	if( tmpReg422&BIT6)
+		bRecover = TRUE;
+	PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2,  tmpReg422&(~BIT6));
+#else
+	// Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
+	if(pHalData->RegFwHwTxQCtrl & BIT(6))
+		bRecover=_TRUE;
+	PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&(~BIT(6))));
+	pHalData->RegFwHwTxQCtrl &= (~ BIT(6));
+#endif
+
+	//---------------------------------------------------------
+	// 2. Adjust LLT table to an even boundary.
+	//---------------------------------------------------------
+#if 0//(DEV_BUS_TYPE == RT_SDIO_INTERFACE)
+	txpktbuf_bndy = 10; // rsvd page start address should be an even value. 														
+	rtStatus =	InitLLTTable8703BS(Adapter, txpktbuf_bndy);
+	if(RT_STATUS_SUCCESS != rtStatus){
+		DBG_8192C("_CheckWLANFwPatchBTFwReady_8703B(): Failed to init LLT!\n");
+		return RT_STATUS_FAILURE;
+	}
+	
+	// Init Tx boundary.
+	PlatformEFIOWrite1Byte(Adapter, REG_DWBCN0_CTRL_8703B+1, (u1Byte)txpktbuf_bndy);	
+#endif
+
+
+	//---------------------------------------------------------
+	// 3. Write Fw to Tx packet buffer by reseverd page.
+	//---------------------------------------------------------
+	do
+	{
+		// download rsvd page.
+		// Clear beacon valid check bit.
+		BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
+		PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+2, BcnValidReg&(~BIT(0)));
+
+		//BT patch is big, we should set 0x209 < 0x40 suggested from Gimmy
+		RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
+					PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));//209 < 0x40
+
+		PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+1, (0x90-0x20*(times-1)));
+		DBG_871X("0x209:0x%x\n", PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1));
+		RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
+					PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));
+
+#if 0
+		// Acquice TX spin lock before GetFwBuf and send the packet to prevent system deadlock.
+		// Advertised by Roger. Added by tynli. 2010.02.22.
+		PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
+		if(MgntGetFWBuffer(Adapter, &pTcb, &pBuf))
+		{
+			PlatformMoveMemory(pBuf->Buffer.VirtualAddress, ReservedPagePacket, TotalPktLen);
+			CmdSendPacket(Adapter, pTcb, pBuf, TotalPktLen, DESC_PACKET_TYPE_NORMAL, FALSE);
+		}
+		else
+			dbgdump("SetFwRsvdPagePkt(): MgntGetFWBuffer FAIL!!!!!!!!.\n");
+		PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
+#else
+		/*---------------------------------------------------------
+		tx reserved_page_packet
+		----------------------------------------------------------*/
+			if ((pmgntframe = rtw_alloc_cmdxmitframe(pxmitpriv)) == NULL) {
+					rtStatus = _FAIL;
+					goto exit;
+			}
+			//update attribute
+			pattrib = &pmgntframe->attrib;
+			update_mgntframe_attrib(Adapter, pattrib);
+
+			pattrib->qsel = QSLT_BEACON;
+			pattrib->pktlen = pattrib->last_txcmdsz = FwBufLen ;
+
+			//_rtw_memset(pmgntframe->buf_addr, 0, TotalPktLen+txdesc_size);
+			//pmgntframe->buf_addr = ReservedPagePacket ;
+
+			_rtw_memcpy( (u8*) (pmgntframe->buf_addr + txdesc_offset), ReservedPagePacket, FwBufLen);
+			DBG_871X("[%d]===>TotalPktLen + TXDESC_OFFSET TotalPacketLen:%d \n", DLBcnCount, (FwBufLen + txdesc_offset));
+			
+#ifdef CONFIG_PCI_HCI
+			dump_mgntframe(Adapter, pmgntframe);
+#else
+			dump_mgntframe_and_wait(Adapter, pmgntframe, 100);
+#endif
+
+#endif
+#if 1
+		// check rsvd page download OK.
+		BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
+		while(!(BcnValidReg & BIT(0)) && count <200)
+		{
+			count++;
+			//PlatformSleepUs(10);
+			rtw_msleep_os(1);
+			BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
+			RT_TRACE(_module_mp_, _drv_notice_,("Poll 0x20A = %x\n", BcnValidReg));
+		}
+		DLBcnCount++;
+		//DBG_871X("##0x208:%08x,0x210=%08x\n",PlatformEFIORead4Byte(Adapter, REG_TDECTRL),PlatformEFIORead4Byte(Adapter, 0x210));
+
+		PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+2,BcnValidReg);
+		
+	}while((!(BcnValidReg&BIT(0))) && DLBcnCount<5);
+
+
+#endif
+	if(DLBcnCount >=5){
+		DBG_871X(" check rsvd page download OK DLBcnCount =%d  \n",DLBcnCount);
+		rtStatus = _FAIL;
+		goto exit;
+	}
+
+	if(!(BcnValidReg&BIT(0)))
+	{
+		DBG_871X("_WriteFWtoTxPktBuf(): 1 Download RSVD page failed!\n");
+		rtStatus = _FAIL;
+		goto exit;
+	}
+
+	//---------------------------------------------------------
+	// 4. Set Tx boundary to the initial value
+	//---------------------------------------------------------
+
+
+	//---------------------------------------------------------
+	// 5. Reset beacon setting to the initial value.
+	//	 After _CheckWLANFwPatchBTFwReady().
+	//---------------------------------------------------------
+
+exit:
+
+	if(pGenBufReservedPagePacket)
+	{
+		DBG_871X("_WriteBTFWtoTxPktBuf8703B => rtw_mfree pGenBufReservedPagePacket!\n");
+		rtw_mfree((u8*)pGenBufReservedPagePacket, TotalPktLen);
+		}
+	return rtStatus;
+}
+
+
+
+//
+// Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW.
+// 2011.10.20 by tynli
+//
+void
+SetFwBTFwPatchCmd(
+	IN PADAPTER	Adapter,
+	IN u16		FwSize
+	)
+{
+	u8 u1BTFwPatchParm[H2C_BT_FW_PATCH_LEN]={0};
+	u8 addr0 = 0;
+	u8 addr1 = 0xa0;
+	u8 addr2 = 0x10;
+	u8 addr3 = 0x80;
+	
+	RT_TRACE(_module_mp_, _drv_notice_,("SetFwBTFwPatchCmd(): FwSize = %d\n", FwSize));
+
+	SET_8703B_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize);
+	SET_8703B_H2CCMD_BT_FW_PATCH_ADDR0(u1BTFwPatchParm, addr0);
+	SET_8703B_H2CCMD_BT_FW_PATCH_ADDR1(u1BTFwPatchParm, addr1);
+	SET_8703B_H2CCMD_BT_FW_PATCH_ADDR2(u1BTFwPatchParm, addr2);
+	SET_8703B_H2CCMD_BT_FW_PATCH_ADDR3(u1BTFwPatchParm, addr3);
+
+	FillH2CCmd8703B(Adapter, H2C_8703B_BT_FW_PATCH, H2C_BT_FW_PATCH_LEN, u1BTFwPatchParm);
+
+	RT_TRACE(_module_mp_, _drv_notice_,("<----SetFwBTFwPatchCmd(): FwSize = %d \n", FwSize));
+}
+
+void
+SetFwBTPwrCmd(
+	IN PADAPTER	Adapter,
+	IN u1Byte	PwrIdx
+	)
+{
+	u1Byte		u1BTPwrIdxParm[H2C_FORCE_BT_TXPWR_LEN]={0};
+
+	RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): idx = %d\n", PwrIdx));
+	SET_8703B_H2CCMD_BT_PWR_IDX(u1BTPwrIdxParm, PwrIdx);
+
+	RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): %x %x %x\n",
+		u1BTPwrIdxParm[0],u1BTPwrIdxParm[1],u1BTPwrIdxParm[2]));
+
+	FillH2CCmd8703B(Adapter, H2C_8703B_FORCE_BT_TXPWR, H2C_FORCE_BT_TXPWR_LEN, u1BTPwrIdxParm);
+}
+
+//
+// Description: WLAN Fw will write BT Fw to BT XRAM and signal driver.
+//
+// 2011.10.20. by tynli.
+//
+int
+_CheckWLANFwPatchBTFwReady(
+	IN	PADAPTER			Adapter
+)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	u4Byte	count=0;
+	u1Byte	u1bTmp;
+	int ret = _FAIL;
+
+	//---------------------------------------------------------
+	// Check if BT FW patch procedure is ready.
+	//---------------------------------------------------------
+	do{
+		u1bTmp = PlatformEFIORead1Byte(Adapter, REG_HMEBOX_DBG_0_8703B);
+		if((u1bTmp&BIT6) || (u1bTmp&BIT7))
+		{
+			ret = _SUCCESS;
+			break;
+		}
+
+		count++;
+		RT_TRACE(_module_mp_, _drv_info_,("0x88=%x, wait for 50 ms (%d) times.\n",
+					u1bTmp, count));
+		rtw_msleep_os(50); // 50ms
+	}while(!((u1bTmp&BIT6) || (u1bTmp&BIT7)) && count < 50);
+
+	RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
+				" Polling ready bit 0x88[7] for %d times.\n", count));
+
+	if(count >= 50)
+	{
+		RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
+				" Polling ready bit 0x88[7] FAIL!!\n"));
+	}
+
+	//---------------------------------------------------------
+	// Reset beacon setting to the initial value.
+	//---------------------------------------------------------
+#if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
+	if(LLT_table_init(Adapter, FALSE, 0) == RT_STATUS_FAILURE)
+	{
+		dbgdump("Init self define for BT Fw patch LLT table fail.\n");
+		//return RT_STATUS_FAILURE;
+	}
+#endif
+	u1bTmp = rtw_read8(Adapter, REG_BCN_CTRL);
+	u1bTmp |= EN_BCN_FUNCTION;
+	u1bTmp &= ~DIS_TSF_UDT;
+	rtw_write8(Adapter, REG_BCN_CTRL, u1bTmp);
+
+	// To make sure that if there exists an adapter which would like to send beacon.
+	// If exists, the origianl value of 0x422[6] will be 1, we should check this to
+	// prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
+	// the beacon cannot be sent by HW.
+	// 2010.06.23. Added by tynli.
+#if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
+	u1bTmp = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL+2);
+	PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (u1bTmp|BIT6));
+#else
+	PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT(6)));
+	pHalData->RegFwHwTxQCtrl |= BIT(6);
+#endif
+
+	// Clear CR[8] or beacon packet will not be send to TxBuf anymore.
+	u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR+1);
+	PlatformEFIOWrite1Byte(Adapter, REG_CR+1, (u1bTmp&(~BIT0)));
+
+	return ret;
+}
+
+int ReservedPage_Compare(PADAPTER Adapter,PRT_MP_FIRMWARE pFirmware,u32 BTPatchSize)
+{
+	u8 temp,ret,lastBTsz;
+	u32 u1bTmp=0,address_start=0,count=0,i=0;
+	u8	*myBTFwBuffer = NULL;
+
+	myBTFwBuffer = rtw_zmalloc(BTPatchSize);
+	if (myBTFwBuffer == NULL)
+	{
+		DBG_871X("%s can't be executed due to the failed malloc.\n", __FUNCTION__);
+		Adapter->mppriv.bTxBufCkFail=_TRUE;
+		return _FALSE;
+	}
+	
+	temp=rtw_read8(Adapter,0x209);
+	
+	address_start=(temp*128)/8;
+	
+	rtw_write32(Adapter,0x140,0x00000000);
+	rtw_write32(Adapter,0x144,0x00000000);
+	rtw_write32(Adapter,0x148,0x00000000);
+
+	rtw_write8(Adapter,0x106,0x69);
+	
+	for(i=0;i<(BTPatchSize/8);i++)
+	{
+		rtw_write32(Adapter,0x140,address_start+5+i) ;		  
+			
+		//polling until reg 0x140[23]=1;
+		do{
+			u1bTmp = rtw_read32(Adapter, 0x140);
+			if(u1bTmp&BIT(23))
+			{
+				ret = _SUCCESS;
+				break;
+			}
+			count++;
+			DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n",u1bTmp, count);
+			rtw_msleep_os(10); // 10ms
+		}while(!(u1bTmp&BIT(23)) && count < 50);
+		
+			myBTFwBuffer[i*8+0]=rtw_read8(Adapter, 0x144);
+			myBTFwBuffer[i*8+1]=rtw_read8(Adapter, 0x145);
+			myBTFwBuffer[i*8+2]=rtw_read8(Adapter, 0x146); 
+			myBTFwBuffer[i*8+3]=rtw_read8(Adapter, 0x147);
+			myBTFwBuffer[i*8+4]=rtw_read8(Adapter, 0x148);
+			myBTFwBuffer[i*8+5]=rtw_read8(Adapter, 0x149);
+			myBTFwBuffer[i*8+6]=rtw_read8(Adapter, 0x14a);
+			myBTFwBuffer[i*8+7]=rtw_read8(Adapter, 0x14b);
+	}
+	
+	rtw_write32(Adapter,0x140,address_start+5+BTPatchSize/8) ;			  
+
+	lastBTsz=BTPatchSize%8;
+	
+	//polling until reg 0x140[23]=1;
+	u1bTmp=0;
+	count=0;
+	do{
+			u1bTmp = rtw_read32(Adapter, 0x140);
+			if(u1bTmp&BIT(23))
+			{
+				ret = _SUCCESS;
+				break;
+			}
+			count++;
+			DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n",u1bTmp, count);
+			rtw_msleep_os(10); // 10ms
+	}while(!(u1bTmp&BIT(23)) && count < 50);
+
+	for(i=0;i<lastBTsz;i++)
+	{
+		myBTFwBuffer[(BTPatchSize/8)*8+i] = rtw_read8(Adapter, (0x144+i));
+
+	}
+
+	for(i=0;i<BTPatchSize;i++)
+	{
+		if(myBTFwBuffer[i]!= pFirmware->szFwBuffer[i])
+		{
+			DBG_871X(" In direct myBTFwBuffer[%d]=%x , pFirmware->szFwBuffer=%x\n",i, myBTFwBuffer[i],pFirmware->szFwBuffer[i]);
+			Adapter->mppriv.bTxBufCkFail=_TRUE;
+			break;
+		}
+	}
+
+	if (myBTFwBuffer != NULL)
+	{
+		rtw_mfree(myBTFwBuffer, BTPatchSize);
+	}
+
+	return _TRUE;
+}
+
+/* As the size of bt firmware is more than 16k which is too big for some platforms, we divide it
+ * into four parts to transfer. The last parameter of _WriteBTFWtoTxPktBuf8703B is used to indicate
+ * the location of every part. We call the first 4096 byte of bt firmware as part 1, the second 4096
+ * part as part 2, the third 4096 part as part 3, the remain as part 4. First we transform the part
+ * 4 and set the register 0x209 to 0x90, then the 32 bytes description are added to the head of part
+ * 4, and those bytes are putted at the location 0x90. Second we transform the part 3 and set the 
+ * register 0x209 to 0x70. The 32 bytes description and part 3(4196 bytes) are putted at the location
+ * 0x70. It can contain 4196 bytes between 0x70 and 0x90. So the last 32 bytes os part 3 will cover the
+ * 32 bytes description of part4. Using this method, we can put the whole bt firmware to 0x30 and only
+ * has 32 bytes descrption at the head of part 1.    
+*/
+s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware)
+{
+	s32 rtStatus;
+	u8 *pBTFirmwareBuf;
+	u32 BTFirmwareLen;
+	u8 download_time;
+	s8 i;
+
+
+	rtStatus = _SUCCESS;
+	pBTFirmwareBuf = NULL;
+	BTFirmwareLen = 0;
+
+#if 0
+	//
+	// Patch BT Fw. Download BT RAM code to Tx packet buffer.
+	//
+	if (padapter->bBTFWReady) {
+		DBG_8192C("%s: BT Firmware is ready!!\n", __FUNCTION__);
+		return _FAIL;
+	}
+
+#ifdef CONFIG_FILE_FWIMG
+	if (rtw_is_file_readable(rtw_fw_mp_bt_file_path) == _TRUE)
+	{
+		DBG_8192C("%s: accquire MP BT FW from file:%s\n", __FUNCTION__, rtw_fw_mp_bt_file_path);
+
+		rtStatus = rtw_retrieve_from_file(rtw_fw_mp_bt_file_path, FwBuffer, FW_8703B_SIZE);
+		BTFirmwareLen = rtStatus>=0?rtStatus:0;
+		pBTFirmwareBuf = FwBuffer;
+	}
+	else
+#endif // CONFIG_FILE_FWIMG
+	{
+#ifdef CONFIG_EMBEDDED_FWIMG
+		DBG_8192C("%s: Download MP BT FW from header\n", __FUNCTION__);
+
+		pBTFirmwareBuf = (u8*)Rtl8703BFwBTImgArray;
+		BTFirmwareLen = Rtl8703BFwBTImgArrayLength;
+		pFirmware->szFwBuffer = pBTFirmwareBuf;
+		pFirmware->ulFwLength = BTFirmwareLen;
+#endif // CONFIG_EMBEDDED_FWIMG
+	}
+
+	DBG_8192C("%s: MP BT Firmware size=%d\n", __FUNCTION__, BTFirmwareLen);
+
+	// for h2c cam here should be set to  true
+	padapter->bFWReady = _TRUE;
+
+	download_time = (BTFirmwareLen + 4095) / 4096;
+	DBG_8192C("%s: download_time is %d\n", __FUNCTION__, download_time);
+
+	// Download BT patch Fw.
+	for (i = (download_time-1); i >= 0; i--)
+	{
+		if (i == (download_time - 1))
+		{
+			rtStatus = _WriteBTFWtoTxPktBuf8703B(padapter, pBTFirmwareBuf+(4096*i), (BTFirmwareLen-(4096*i)), 1);
+			DBG_8192C("%s: start %d, len %d, time 1\n", __FUNCTION__, 4096*i, BTFirmwareLen-(4096*i));
+		}
+		else
+		{
+			rtStatus = _WriteBTFWtoTxPktBuf8703B(padapter, pBTFirmwareBuf+(4096*i), 4096, (download_time-i));
+			DBG_8192C("%s: start %d, len 4096, time %d\n", __FUNCTION__, 4096*i, download_time-i);
+		}
+
+		if (rtStatus != _SUCCESS)
+		{
+			DBG_8192C("%s: BT Firmware download to Tx packet buffer fail!\n", __FUNCTION__);
+			padapter->bBTFWReady = _FALSE;
+			return rtStatus;
+		}
+	}
+
+	ReservedPage_Compare(padapter, pFirmware, BTFirmwareLen);
+
+	padapter->bBTFWReady = _TRUE;
+	SetFwBTFwPatchCmd(padapter, (u16)BTFirmwareLen);
+	rtStatus = _CheckWLANFwPatchBTFwReady(padapter);
+
+	DBG_8192C("<===%s: return %s!\n", __FUNCTION__, rtStatus==_SUCCESS?"SUCCESS":"FAIL");
+#endif
+
+	return rtStatus;
+}
+#endif // CONFIG_MP_INCLUDED
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc)
+{
+	u16	*usPtr = (u16*)ptxdesc;
+	u32 count;
+	u32 index;
+	u16 checksum = 0;
+
+
+	// Clear first
+	ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
+
+	// checksume is always calculated by first 32 bytes,
+	// and it doesn't depend on TX DESC length.
+	// Thomas,Lucas@SD4,20130515
+	count = 16;
+
+	for (index = 0; index < count; index++) {
+		checksum ^= le16_to_cpu(*(usPtr + index));
+	}
+
+	ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
+}
+#endif
+
+#ifdef CONFIG_SDIO_HCI
+u8 send_fw_packet(PADAPTER padapter, u8 *pRam_code, u32 length)
+{
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
+	struct xmit_buf xmit_buf_tmp;
+	struct submit_ctx sctx_tmp;
+	u8 *pTx_data_buffer = NULL;
+	u8 *pTmp_buffer = NULL;
+	u32 modify_ram_size;
+	u32 tmp_size,tmp_value;
+	u8 value8;
+	u32 i,counter;
+	u8  	bRet;
+	u32	dwDataLength, writeLength;
+
+	/* Due to SDIO can not send 32K packet */
+	if (FW_DOWNLOAD_SIZE_8703B == length) {
+		length--;
+	}
+
+	modify_ram_size = length << 2;
+	pTx_data_buffer = rtw_zmalloc(modify_ram_size);
+	
+	if (NULL == pTx_data_buffer) {
+		DBG_871X("Allocate buffer fail!!\n");
+		return _FALSE;
+	}
+
+	_rtw_memset(pTx_data_buffer, 0, modify_ram_size);
+	
+	/* Transfer to new format */
+	tmp_size = length >> 1;	
+	for (i = 0;i <= tmp_size;i++){
+		*(pTx_data_buffer + i * 8) = *(pRam_code + i * 2);
+		*(pTx_data_buffer + i*8 + 1) = *(pRam_code + i * 2 + 1);			
+	}
+
+	/* Gen TX_DESC */
+	_rtw_memset(pTx_data_buffer, 0, TXDESC_SIZE);
+	pTmp_buffer = pTx_data_buffer;
+#if 0	
+	pTmp_buffer->qsel = BcnQsel;
+	pTmp_buffer->txpktsize = modify_ram_size - TXDESC_SIZE;
+	pTmp_buffer->offset = TXDESC_SIZE;
+#else
+	SET_TX_DESC_QUEUE_SEL_8703B(pTmp_buffer, QSLT_BEACON);
+	SET_TX_DESC_PKT_SIZE_8703B(pTmp_buffer, modify_ram_size - TXDESC_SIZE);
+	SET_TX_DESC_OFFSET_8703B(pTmp_buffer, TXDESC_SIZE);
+#endif
+	rtl8703b_cal_txdesc_chksum((struct tx_desc*)pTmp_buffer);
+
+	
+	/* Send packet */
+#if 0
+	dwDataLength = modify_ram_size;
+	overlap.Offset = 0;
+	overlap.OffsetHigh = 0;
+	overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+	bRet = WriteFile(HalVari.hFile_Queue[TX_BCNQ]->handle,pTx_data_buffer,dwDataLength,&writeLength,&overlap);	
+	if(WaitForSingleObject(overlap.hEvent,INFINITE)==WAIT_OBJECT_0){
+
+		GetOverlappedResult(HalVari.hFile_Queue[TX_BCNQ]->handle,&overlap,&writeLength,FALSE);
+		if( writeLength != dwDataLength ){
+			TCHAR editbuf[100];
+			sprintf(editbuf,"DL FW Length Err: Write length error:bRet %d writeLength %ld dwDataLength %ld, Error Code:%ld",bRet,writeLength,dwDataLength,GetLastError());
+			AfxMessageBox(editbuf, MB_OK | MB_ICONERROR);
+			return FALSE;
+		}
+	}
+	CloseHandle(overlap.hEvent);
+#else
+	xmit_buf_tmp.pdata = pTx_data_buffer;
+	xmit_buf_tmp.len = modify_ram_size;
+	rtw_sctx_init(&sctx_tmp, 10);
+	xmit_buf_tmp.sctx = &sctx_tmp;
+	if (rtw_write_port(padapter, pdvobjpriv->Queue2Pipe[BCN_QUEUE_INX], xmit_buf_tmp.len, (u8*)&xmit_buf_tmp) == _FAIL) {
+		DBG_871X("rtw_write_port fail\n");
+		return _FAIL;
+	}
+#endif
+
+	/* check if DMA is OK */
+	counter = 100;
+	do {
+		if (0 == counter) {			
+			DBG_871X("DMA time out!!\n");
+			return _FALSE;
+		}		
+		value8 = rtw_read8(padapter, REG_DWBCN0_CTRL_8703B + 2);	
+		counter--;
+	} while (0 == (value8 & BIT(0)));
+	 
+	rtw_write8(padapter, REG_DWBCN0_CTRL_8703B + 2, value8);
+
+	/* Modify ram code by IO method */	
+	tmp_value = rtw_read8(padapter, REG_MCUFWDL + 1);
+	/* Disable DMA */
+	rtw_write8(padapter, REG_MCUFWDL + 1, (u8)tmp_value & ~(BIT(5)));
+	tmp_value = (tmp_value >> 6) << 1;
+	/* Set page start address */
+	rtw_write8(padapter, REG_MCUFWDL + 2, (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | tmp_value);		
+	tmp_size = TXDESC_SIZE >> 2; /* 10bytes */
+#if 0
+	IO_Func.WriteRegister(0x1000, (u2Byte)tmp_size, pRam_code);
+#else
+	_BlockWrite(padapter, pRam_code, tmp_size);
+#endif
+
+	if (pTmp_buffer != NULL) {
+		rtw_mfree((u8*)pTmp_buffer, modify_ram_size);
+	}
+
+	return _TRUE;
+}
+#endif /* CONFIG_SDIO_HCI */
+
+//
+//	Description:
+//		Download 8192C firmware code.
+//
+//
+s32 rtl8703b_FirmwareDownload(PADAPTER padapter, BOOLEAN  bUsedWoWLANFw)
+{
+	s32	rtStatus = _SUCCESS;
+	u8 write_fw = 0;
+	u32 fwdl_start_time;
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	s8 			R8703BFwImageFileName[] ={RTL8703B_FW_IMG};
+	u8			*FwImage;
+	u32			FwImageLen;
+	u8			*pFwImageFileName;
+#ifdef CONFIG_WOWLAN
+	u8			*FwImageWoWLAN;
+	u32			FwImageWoWLANLen;
+#endif	
+	u8			*pucMappedFile = NULL;
+	PRT_FIRMWARE_8703B	pFirmware = NULL;
+	PRT_8703B_FIRMWARE_HDR		pFwHdr = NULL;
+	u8			*pFirmwareBuf;
+	u32			FirmwareLen;
+#ifdef CONFIG_FILE_FWIMG
+	u8 *fwfilepath;
+#endif // CONFIG_FILE_FWIMG
+	u8			value8;
+	u16			value16;
+	u32			value32;
+	u8 			dma_iram_sel;
+	u16 		new_chk_sum = 0;
+	u32 		send_pkt_size, pkt_size_tmp;
+	u32 		mem_offset;
+	u32			counter;
+	struct dvobj_priv *psdpriv = padapter->dvobj;
+	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+
+	RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __FUNCTION__));
+#ifdef CONFIG_WOWLAN
+	RT_TRACE(_module_hal_init_c_, _drv_notice_, ("+%s, bUsedWoWLANFw:%d\n", __FUNCTION__,bUsedWoWLANFw));
+#endif
+	pFirmware = (PRT_FIRMWARE_8703B)rtw_zmalloc(sizeof(RT_FIRMWARE_8703B));
+
+	if(!pFirmware)
+	{
+		rtStatus = _FAIL;
+		goto exit;
+	}
+
+	{
+			u8 tmp_ps=0, tmp_rf=0;
+			tmp_ps=rtw_read8(padapter,0xa3);
+			tmp_ps&=0xf8;
+			tmp_ps|=0x02;
+			//1. write 0xA3[:2:0] = 3b'010
+			rtw_write8(padapter, 0xa3, tmp_ps);
+			//2. read power_state = 0xA0[1:0]
+			tmp_ps=rtw_read8(padapter,0xa0);
+			tmp_ps&=0x03;
+			if(tmp_ps != 0x01)
+			{
+				DBG_871X(FUNC_ADPT_FMT" tmp_ps=%x \n",FUNC_ADPT_ARG(padapter), tmp_ps);
+				pdbgpriv->dbg_downloadfw_pwr_state_cnt++;
+			}
+	}
+
+#ifdef CONFIG_BT_COEXIST
+	rtw_btcoex_PreLoadFirmware(padapter);
+#endif /* CONFIG_BT_COEXIST */
+	
+#ifdef CONFIG_FILE_FWIMG
+#ifdef CONFIG_WOWLAN
+	if (bUsedWoWLANFw)
+	{
+		fwfilepath = rtw_fw_wow_file_path;
+	}
+	else
+#endif // CONFIG_WOWLAN
+	{
+		fwfilepath = rtw_fw_file_path;
+	}
+#endif // CONFIG_FILE_FWIMG
+
+#ifdef CONFIG_FILE_FWIMG
+	if (rtw_is_file_readable(fwfilepath) == _TRUE)
+	{
+		DBG_8192C("%s accquire FW from file:%s\n", __FUNCTION__, fwfilepath);
+		pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
+	}
+	else
+#endif // CONFIG_FILE_FWIMG
+	{
+#ifdef CONFIG_EMBEDDED_FWIMG
+		pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
+#else // !CONFIG_EMBEDDED_FWIMG
+		pFirmware->eFWSource = FW_SOURCE_IMG_FILE; // We should decided by Reg.
+#endif // !CONFIG_EMBEDDED_FWIMG
+	}
+
+	switch(pFirmware->eFWSource)
+	{
+		case FW_SOURCE_IMG_FILE:
+#ifdef CONFIG_FILE_FWIMG
+			rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer, FW_8703B_SIZE);
+			pFirmware->ulFwLength = rtStatus>=0?rtStatus:0;
+			pFirmware->szFwBuffer = FwBuffer;
+#endif // CONFIG_FILE_FWIMG
+			break;
+
+		case FW_SOURCE_HEADER_FILE:
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+		if (bUsedWoWLANFw) {
+			if (!pwrpriv->wowlan_ap_mode) {
+				ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv,
+						CONFIG_FW_WoWLAN,
+						(u8*)&pFirmware->szFwBuffer,
+						&pFirmware->ulFwLength);
+
+				DBG_8192C(" ===> %s fw: %s, size: %d\n",
+						__FUNCTION__, "WoWLAN",
+						pFirmware->ulFwLength);
+			} else {
+				ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv,
+						CONFIG_FW_AP_WoWLAN,
+						(u8*)&pFirmware->szFwBuffer,
+						&pFirmware->ulFwLength);
+
+				DBG_8192C(" ===> %s fw: %s, size: %d\n",
+						__FUNCTION__, "AP_WoWLAN",
+						pFirmware->ulFwLength);
+			}
+		} else
+#endif // CONFIG_WOWLAN
+			{
+ 				ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_NIC,
+					(u8*)&pFirmware->szFwBuffer, &pFirmware->ulFwLength);
+	 			DBG_8192C("%s fw: %s, size: %d\n", __FUNCTION__, "FW_NIC", pFirmware->ulFwLength);
+			}
+			break;
+	}
+
+	if (pFirmware->ulFwLength > FW_8703B_SIZE) {
+		rtStatus = _FAIL;
+		DBG_871X_LEVEL(_drv_emerg_, "Firmware size:%u exceed %u\n", pFirmware->ulFwLength, FW_8703B_SIZE);
+		goto exit;
+	}
+
+	pFirmwareBuf = pFirmware->szFwBuffer;
+	FirmwareLen = pFirmware->ulFwLength;
+
+	// To Check Fw header. Added by tynli. 2009.12.04.
+	pFwHdr = (PRT_8703B_FIRMWARE_HDR)pFirmwareBuf;
+
+	pHalData->FirmwareVersion =  le16_to_cpu(pFwHdr->Version);
+	pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion);
+	pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
+
+	DBG_871X("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
+		  __FUNCTION__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature
+		  ,pFwHdr->Month,pFwHdr->Date,pFwHdr->Hour,pFwHdr->Minute);
+
+	if (IS_FW_HEADER_EXIST_8703B(pFwHdr))
+	{
+		DBG_871X("%s(): Shift for fw header!\n", __FUNCTION__);
+		// Shift 32 bytes for FW header
+		pFirmwareBuf = pFirmwareBuf + 32;
+		FirmwareLen = FirmwareLen - 32;
+	}
+
+	fwdl_start_time = rtw_get_current_time();
+
+#if 1
+	DBG_871X("%s by IO write!\n", __FUNCTION__);
+
+
+	/* To check if FW already exists before download FW */
+	if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) {
+		rtw_write8(padapter, REG_MCUFWDL, 0x00);
+		_8051Reset8703(padapter);
+	}
+
+	_FWDownloadEnable(padapter, _TRUE);
+
+	while (!RTW_CANNOT_IO(padapter)
+			&& (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500))
+	{
+		/* reset FWDL chksum */
+		rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL)|FWDL_ChkSum_rpt);
+
+		rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
+		if (rtStatus != _SUCCESS)
+			continue;
+
+		rtStatus = polling_fwdl_chksum(padapter, 5, 50);
+		if (rtStatus == _SUCCESS)
+			break;
+	}
+#else
+	DBG_871X("%s by Tx pkt write!\n", __FUNCTION__);
+
+	if ((rtw_read8(padapter, REG_MCUFWDL) & MCUFWDL_RDY) == 0) {
+		/* DLFW use HIQ only */
+		value32 = 0xFF | BIT(31);
+		rtw_write32(padapter, REG_RQPN, value32);
+
+		/* Set beacon boundary to TXFIFO header */
+		rtw_write8(padapter, REG_BCNQ_BDNY, 0);	
+		rtw_write16(padapter, REG_DWBCN0_CTRL_8703B + 1, BIT(8));
+
+		/* SDIO need read this register before send packet */
+		rtw_read32(padapter, 0x10250020);
+
+		_FWDownloadEnable(padapter, _TRUE);
+
+		/* Get original check sum */
+		new_chk_sum = *(pFirmwareBuf + FirmwareLen - 2) | ((u16)*(pFirmwareBuf + FirmwareLen - 1) << 8);
+
+		/* Send ram code flow */
+		dma_iram_sel = 0;
+		mem_offset = 0;
+		pkt_size_tmp = FirmwareLen;
+		while (0 != pkt_size_tmp) {		
+			if (pkt_size_tmp >= FW_DOWNLOAD_SIZE_8703B) {
+				send_pkt_size = FW_DOWNLOAD_SIZE_8703B;
+				/* Modify check sum value */
+				new_chk_sum = (u16)(new_chk_sum ^ (((send_pkt_size - 1) << 2) - TXDESC_SIZE));
+			}
+			else{
+				send_pkt_size = pkt_size_tmp;		
+				new_chk_sum = (u16)(new_chk_sum ^ ((send_pkt_size << 2) - TXDESC_SIZE));
+
+			}
+
+			if (send_pkt_size == pkt_size_tmp) {
+				/* last partition packet, write new check sum to ram code file */
+				*(pFirmwareBuf + FirmwareLen - 2) = new_chk_sum & 0xFF;
+				*(pFirmwareBuf + FirmwareLen - 1) = (new_chk_sum & 0xFF00) >> 8;
+			}
+
+			/* IRAM select */
+			rtw_write8(padapter, REG_MCUFWDL + 1, (rtw_read8(padapter, REG_MCUFWDL + 1) & 0x3F) | (dma_iram_sel << 6));
+			/* Enable DMA */
+			rtw_write8(padapter, REG_MCUFWDL + 1, rtw_read8(padapter, REG_MCUFWDL + 1) | BIT(5));
+
+			if (_FALSE == send_fw_packet(padapter, pFirmwareBuf + mem_offset, send_pkt_size)) {	
+				DBG_871X("%s: Send FW fail !\n", __FUNCTION__);
+				rtStatus = _FAIL;
+				goto DLFW_FAIL;
+			}
+			
+			dma_iram_sel++;
+			mem_offset += send_pkt_size;
+			pkt_size_tmp -= send_pkt_size;
+		}
+	} else {
+		DBG_871X("%s: Downlad FW fail since MCUFWDL_RDY is not set!\n", __FUNCTION__);
+		rtStatus = _FAIL;
+		goto DLFW_FAIL;
+	}
+#endif
+
+	_FWDownloadEnable(padapter, _FALSE);
+
+	rtStatus = _FWFreeToGo(padapter, 10, 200);
+	if (_SUCCESS != rtStatus)
+		goto DLFW_FAIL;
+
+	DBG_871X("%s: DLFW OK !\n", __FUNCTION__);
+
+DLFW_FAIL:
+	if (rtStatus == _FAIL) {
+		/* Disable FWDL_EN */
+		value8 = rtw_read8(padapter, REG_MCUFWDL);
+		value8 = (value8 & ~(BIT(0)) & ~(BIT(1)));
+		rtw_write8(padapter, REG_MCUFWDL, value8);
+	}
+	
+	DBG_871X("%s %s. write_fw:%u, %dms\n"
+		, __FUNCTION__, (rtStatus == _SUCCESS)?"success":"fail"
+		, write_fw
+		, rtw_get_passing_time_ms(fwdl_start_time)
+	);
+
+exit:
+	if (pFirmware)
+		rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_8703B));
+
+	rtl8703b_InitializeFirmwareVars(padapter);
+	
+	DBG_871X(" <=== %s()\n", __FUNCTION__);
+
+	return rtStatus;
+}
+
+void rtl8703b_InitializeFirmwareVars(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+	// Init Fw LPS related.
+	adapter_to_pwrctl(padapter)->bFwCurrentInPSMode = _FALSE;
+
+	//Init H2C cmd.
+	rtw_write8(padapter, REG_HMETFR, 0x0f);
+	
+	// Init H2C counter. by tynli. 2009.12.09.
+	pHalData->LastHMEBoxNum = 0;
+//	pHalData->H2CQueueHead = 0;
+//	pHalData->H2CQueueTail = 0;
+//	pHalData->H2CStopInsertQueue = _FALSE;
+}
+
+//===========================================================
+//				Efuse related code
+//===========================================================
+static u8
+hal_EfuseSwitchToBank(
+	PADAPTER	padapter,
+	u8			bank,
+	u8			bPseudoTest)
+{
+	u8 bRet = _FALSE;
+	u32 value32 = 0;
+#ifdef HAL_EFUSE_MEMORY
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
+#endif
+
+
+	DBG_8192C("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
+	if (bPseudoTest)
+	{
+#ifdef HAL_EFUSE_MEMORY
+		pEfuseHal->fakeEfuseBank = bank;
+#else
+		fakeEfuseBank = bank;
+#endif
+		bRet = _TRUE;
+	}
+	else
+	{
+		value32 = rtw_read32(padapter, EFUSE_TEST);
+		bRet = _TRUE;
+		switch (bank)
+		{
+			case 0:
+				value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
+				break;
+			case 1:
+				value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
+				break;
+			case 2:
+				value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
+				break;
+			case 3:
+				value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
+				break;
+			default:
+				value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
+				bRet = _FALSE;
+				break;
+		}
+		rtw_write32(padapter, EFUSE_TEST, value32);
+	}
+
+	return bRet;
+}
+
+static void
+Hal_GetEfuseDefinition(
+	PADAPTER	padapter,
+	u8			efuseType,
+	u8			type,
+	void		*pOut,
+	u8			bPseudoTest)
+{
+	switch (type)
+	{
+		case TYPE_EFUSE_MAX_SECTION:
+			{
+				u8 *pMax_section;
+				pMax_section = (u8*)pOut;
+
+				if (efuseType == EFUSE_WIFI)
+					*pMax_section = EFUSE_MAX_SECTION_8703B;
+				else
+					*pMax_section = EFUSE_BT_MAX_SECTION;
+			}
+			break;
+
+		case TYPE_EFUSE_REAL_CONTENT_LEN:
+			{
+				u16 *pu2Tmp;
+				pu2Tmp = (u16*)pOut;
+
+				if (efuseType == EFUSE_WIFI)
+					*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8703B;
+				else
+					*pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
+			}
+			break;
+
+		case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
+			{
+				u16	*pu2Tmp;
+				pu2Tmp = (u16*)pOut;
+
+				if (efuseType == EFUSE_WIFI)
+					*pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8703B-EFUSE_OOB_PROTECT_BYTES);
+				else
+					*pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK);
+			}
+			break;
+
+		case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
+			{
+				u16 *pu2Tmp;
+				pu2Tmp = (u16*)pOut;
+
+				if (efuseType == EFUSE_WIFI)
+					*pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8703B-EFUSE_OOB_PROTECT_BYTES);
+				else
+					*pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN-(EFUSE_PROTECT_BYTES_BANK*3));
+			}
+			break;
+
+		case TYPE_EFUSE_MAP_LEN:
+			{
+				u16 *pu2Tmp;
+				pu2Tmp = (u16*)pOut;
+
+				if (efuseType == EFUSE_WIFI)
+					*pu2Tmp = EFUSE_MAX_MAP_LEN;
+				else
+					*pu2Tmp = EFUSE_BT_MAP_LEN;
+			}
+			break;
+
+		case TYPE_EFUSE_PROTECT_BYTES_BANK:
+			{
+				u8 *pu1Tmp;
+				pu1Tmp = (u8*)pOut;
+
+				if (efuseType == EFUSE_WIFI)
+					*pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
+				else
+					*pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
+			}
+			break;
+
+		case TYPE_EFUSE_CONTENT_LEN_BANK:
+			{
+				u16 *pu2Tmp;
+				pu2Tmp = (u16*)pOut;
+
+				if (efuseType == EFUSE_WIFI)
+					*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8703B;
+				else
+					*pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
+			}
+			break;
+
+		default:
+			{
+				u8 *pu1Tmp;
+				pu1Tmp = (u8*)pOut;
+				*pu1Tmp = 0;
+			}
+			break;
+	}
+}
+
+#define VOLTAGE_V25		0x03
+#define LDOE25_SHIFT	28
+
+//=================================================================
+//	The following is for compile ok
+//	That should be merged with the original in the future
+//=================================================================
+#define EFUSE_ACCESS_ON_8703			0x69	// For RTL8703 only.
+#define EFUSE_ACCESS_OFF_8703			0x00	// For RTL8703 only.
+#define REG_EFUSE_ACCESS_8703			0x00CF	// Efuse access protection for RTL8703
+
+//=================================================================
+static void Hal_BT_EfusePowerSwitch(
+	PADAPTER	padapter,
+	u8			bWrite,
+	u8			PwrState)
+{
+	u8 tempval;
+	if (PwrState == _TRUE)
+	{
+		// enable BT power cut
+		// 0x6A[14] = 1
+		tempval = rtw_read8(padapter, 0x6B);
+		tempval |= BIT(6);
+		rtw_write8(padapter, 0x6B, tempval);
+		
+		// Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
+		// So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
+		rtw_usleep_os(100);
+		// disable BT output isolation
+		// 0x6A[15] = 0
+		tempval = rtw_read8(padapter, 0x6B);
+		tempval &= ~BIT(7);
+		rtw_write8(padapter, 0x6B, tempval);
+	}
+	else
+	{
+		// enable BT output isolation
+		// 0x6A[15] = 1
+		tempval = rtw_read8(padapter, 0x6B);
+		tempval |= BIT(7);
+		rtw_write8(padapter, 0x6B, tempval);
+
+		// Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
+		// So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
+
+		// disable BT power cut
+		// 0x6A[14] = 1
+		tempval = rtw_read8(padapter, 0x6B);
+		tempval &= ~BIT(6);
+		rtw_write8(padapter, 0x6B, tempval);
+	}
+
+}
+static void
+Hal_EfusePowerSwitch(
+	PADAPTER	padapter,
+	u8			bWrite,
+	u8			PwrState)
+{
+	u8	tempval;
+	u16	tmpV16;
+
+
+	if (PwrState == _TRUE)
+	{
+#ifdef CONFIG_SDIO_HCI
+		// To avoid cannot access efuse regsiters after disable/enable several times during DTM test. 
+		// Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli. 
+		tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
+		if (tempval & BIT(0)) // SDIO local register is suspend
+		{
+			u8 count = 0;
+
+
+			tempval &= ~BIT(0);
+			rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL, tempval);
+
+			// check 0x86[1:0]=10'2h, wait power state to leave suspend
+ 			do {
+				tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
+				tempval &= 0x3;
+				if (tempval == 0x02)
+					break;
+
+				count++;
+				if (count >= 100)
+					break;
+
+				rtw_mdelay_os(10);
+			} while (1);
+
+			if (count >= 100)
+			{
+				DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend fail! Local 0x86=%#X\n",
+					FUNC_ADPT_ARG(padapter), tempval);
+			}
+			else
+			{
+				DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend OK! Local 0x86=%#X\n",
+					FUNC_ADPT_ARG(padapter), tempval);
+		}
+		}
+#endif // CONFIG_SDIO_HCI
+
+		rtw_write8(padapter, REG_EFUSE_ACCESS_8703, EFUSE_ACCESS_ON_8703);	
+
+		// Reset: 0x0000h[28], default valid
+		tmpV16 =  rtw_read16(padapter, REG_SYS_FUNC_EN);
+		if (!(tmpV16 & FEN_ELDR)) {
+			tmpV16 |= FEN_ELDR ;
+			rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
+		}
+
+		// Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
+		tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
+		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
+			tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
+			rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
+		}
+
+		if (bWrite == _TRUE)
+		{
+			// Enable LDO 2.5V before read/write action
+			tempval = rtw_read8(padapter, EFUSE_TEST+3);
+			tempval &= 0x0F;
+			tempval |= (VOLTAGE_V25 << 4);
+			rtw_write8(padapter, EFUSE_TEST+3, (tempval | 0x80));
+
+			//rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
+		}
+	}
+	else
+	{
+		rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
+
+		if (bWrite == _TRUE) {
+			// Disable LDO 2.5V after read/write action
+			tempval = rtw_read8(padapter, EFUSE_TEST+3);
+			rtw_write8(padapter, EFUSE_TEST+3, (tempval & 0x7F));
+		}
+
+	}
+}
+
+static void
+hal_ReadEFuse_WiFi(
+	PADAPTER	padapter,
+	u16			_offset,
+	u16			_size_byte,
+	u8			*pbuf,
+	u8			bPseudoTest)
+{
+#ifdef HAL_EFUSE_MEMORY
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PEFUSE_HAL		pEfuseHal = &pHalData->EfuseHal;
+#endif
+	u8	*efuseTbl = NULL;
+	u16	eFuse_Addr=0;
+	u8	offset, wden;
+	u8	efuseHeader, efuseExtHdr, efuseData;
+	u16	i, total, used;
+	u8	efuse_usage = 0;
+
+	//DBG_871X("YJ: ====>%s():_offset=%d _size_byte=%d bPseudoTest=%d\n", __func__, _offset, _size_byte, bPseudoTest);
+	//
+	// Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
+	//
+	if ((_offset+_size_byte) > EFUSE_MAX_MAP_LEN)
+	{
+		DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
+		return;
+	}
+
+	efuseTbl = (u8*)rtw_malloc(EFUSE_MAX_MAP_LEN);
+	if (efuseTbl == NULL)
+	{
+		DBG_8192C("%s: alloc efuseTbl fail!\n", __FUNCTION__);
+		return;
+	}
+	// 0xff will be efuse default value instead of 0x00.
+	_rtw_memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN);
+
+
+#ifdef CONFIG_DEBUG
+if(0)
+{
+	for(i=0; i<256; i++)
+		//ReadEFuseByte(padapter, i, &efuseTbl[i], _FALSE);
+		efuse_OneByteRead(padapter, i, &efuseTbl[i], _FALSE);
+	DBG_871X("Efuse Content:\n");
+	for(i=0; i<256; i++)
+	{
+		if (i % 16 == 0)
+			printk("\n");
+		printk("%02X ", efuseTbl[i]);
+	}
+	printk("\n");
+}
+#endif
+
+
+	// switch bank back to bank 0 for later BT and wifi use.
+	hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
+
+	while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
+	{
+		//ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
+		efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
+		if (efuseHeader == 0xFF)
+		{
+			DBG_8192C("%s: data end at address=%#x\n", __FUNCTION__, eFuse_Addr-1);
+			break;
+		}
+		//DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseHeader);
+
+		// Check PG header for section num.
+		if (EXT_HEADER(efuseHeader))		//extended header
+		{
+			offset = GET_HDR_OFFSET_2_0(efuseHeader);
+			//DBG_8192C("%s: extended header offset=0x%X\n", __FUNCTION__, offset);
+
+			//ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
+			efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
+			//DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseExtHdr);
+			if (ALL_WORDS_DISABLED(efuseExtHdr))
+			{
+				continue;
+			}
+
+			offset |= ((efuseExtHdr & 0xF0) >> 1);
+			wden = (efuseExtHdr & 0x0F);
+		}
+		else
+		{
+			offset = ((efuseHeader >> 4) & 0x0f);
+			wden = (efuseHeader & 0x0f);
+		}
+		//DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
+
+		if (offset < EFUSE_MAX_SECTION_8703B)
+		{
+			u16 addr;
+			// Get word enable value from PG header
+//			DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
+
+			addr = offset * PGPKT_DATA_SIZE;
+			for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
+			{
+				// Check word enable condition in the section
+				if (!(wden & (0x01<<i)))
+				{
+					efuseData = 0;
+					//ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
+					efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
+//					DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
+					efuseTbl[addr] = efuseData;
+
+					efuseData = 0;
+					//ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
+					efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
+//					DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
+					efuseTbl[addr+1] = efuseData;
+				}
+				addr += 2;
+			}
+		}
+		else
+		{
+			DBG_8192C(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
+			eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
+		}
+	}
+
+	// Copy from Efuse map to output pointer memory!!!
+	for (i=0; i<_size_byte; i++)
+		pbuf[i] = efuseTbl[_offset+i];
+
+#ifdef CONFIG_DEBUG
+if(1)
+{
+	DBG_871X("Efuse Realmap:\n");
+	for(i=0; i<_size_byte; i++)
+	{
+		if (i % 16 == 0)
+			printk("\n");
+		printk("%02X ", pbuf[i]);
+	}
+	printk("\n");
+}
+#endif
+	// Calculate Efuse utilization
+	total = 0;
+	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
+	used = eFuse_Addr - 1;
+	if (total)
+		efuse_usage = (u8)((used*100)/total);
+	else
+		efuse_usage = 100;
+	if (bPseudoTest)
+	{
+#ifdef HAL_EFUSE_MEMORY
+		pEfuseHal->fakeEfuseUsedBytes = used;
+#else
+		fakeEfuseUsedBytes = used;
+#endif
+	}
+	else
+	{
+		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&used);
+		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8*)&efuse_usage);
+	}
+
+	if (efuseTbl)
+		rtw_mfree(efuseTbl, EFUSE_MAX_MAP_LEN);
+}
+
+static VOID
+hal_ReadEFuse_BT(
+	PADAPTER	padapter,
+	u16			_offset,
+	u16			_size_byte,
+	u8			*pbuf,
+	u8			bPseudoTest
+	)
+{
+#ifdef HAL_EFUSE_MEMORY
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PEFUSE_HAL		pEfuseHal = &pHalData->EfuseHal;
+#endif
+	u8	*efuseTbl;
+	u8	bank;
+	u16	eFuse_Addr;
+	u8	efuseHeader, efuseExtHdr, efuseData;
+	u8	offset, wden;
+	u16	i, total, used;
+	u8	efuse_usage;
+
+
+	//
+	// Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
+	//
+	if ((_offset+_size_byte) > EFUSE_BT_MAP_LEN)
+	{
+		DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
+		return;
+	}
+
+	efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
+	if (efuseTbl == NULL) {
+		DBG_8192C("%s: efuseTbl malloc fail!\n", __FUNCTION__);
+		return;
+	}
+	// 0xff will be efuse default value instead of 0x00.
+	_rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
+
+	total = 0;
+	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
+
+	for (bank=1; bank<3; bank++) // 8703b Max bake 0~2
+	{
+		if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
+		{
+			DBG_8192C("%s: hal_EfuseSwitchToBank Fail!!\n", __FUNCTION__);
+			goto exit;
+		}
+
+		eFuse_Addr = 0;
+
+		while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
+		{
+			//ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
+			efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
+			if (efuseHeader == 0xFF) break;
+			DBG_8192C("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN_8703B)+eFuse_Addr-1), efuseHeader);
+
+			// Check PG header for section num.
+			if (EXT_HEADER(efuseHeader))		//extended header
+			{
+				offset = GET_HDR_OFFSET_2_0(efuseHeader);
+				DBG_8192C("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset);
+
+				//ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
+				efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
+				DBG_8192C("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN_8703B)+eFuse_Addr-1), efuseExtHdr);
+				if (ALL_WORDS_DISABLED(efuseExtHdr))
+				{
+					continue;
+				}
+
+				offset |= ((efuseExtHdr & 0xF0) >> 1);
+				wden = (efuseExtHdr & 0x0F);
+			}
+			else
+			{
+				offset = ((efuseHeader >> 4) & 0x0f);
+				wden = (efuseHeader & 0x0f);
+			}
+
+			if (offset < EFUSE_BT_MAX_SECTION)
+			{
+				u16 addr;
+
+				// Get word enable value from PG header
+				DBG_8192C("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
+
+				addr = offset * PGPKT_DATA_SIZE;
+				for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
+				{
+					// Check word enable condition in the section
+					if (!(wden & (0x01<<i)))
+					{
+						efuseData = 0;
+						//ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
+						efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
+						DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
+						efuseTbl[addr] = efuseData;
+
+						efuseData = 0;
+						//ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
+						efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
+						DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
+						efuseTbl[addr+1] = efuseData;
+					}
+					addr += 2;
+				}
+			}
+			else
+			{
+				DBG_8192C("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
+				eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
+			}
+		}
+
+		if ((eFuse_Addr-1) < total)
+		{
+			DBG_8192C("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr-1);
+			break;
+		}
+	}
+
+	// switch bank back to bank 0 for later BT and wifi use.
+	hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
+
+	// Copy from Efuse map to output pointer memory!!!
+	for (i=0; i<_size_byte; i++)
+		pbuf[i] = efuseTbl[_offset+i];
+
+	//
+	// Calculate Efuse utilization.
+	//
+	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
+	used = (EFUSE_BT_REAL_BANK_CONTENT_LEN*(bank-1)) + eFuse_Addr - 1;
+	DBG_8192C("%s: bank(%d) data end at %#x ,used =%d\n", __FUNCTION__, bank, eFuse_Addr-1,used);
+	efuse_usage = (u8)((used*100)/total);
+	if (bPseudoTest)
+	{
+#ifdef HAL_EFUSE_MEMORY
+		pEfuseHal->fakeBTEfuseUsedBytes = used;
+#else
+		fakeBTEfuseUsedBytes = used;
+#endif
+	}
+	else
+	{
+		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&used);
+		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8*)&efuse_usage);
+	}
+
+exit:
+	if (efuseTbl)
+		rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);
+}
+
+static void
+Hal_ReadEFuse(
+	PADAPTER	padapter,
+	u8			efuseType,
+	u16			_offset,
+	u16			_size_byte,
+	u8			*pbuf,
+	u8			bPseudoTest)
+{
+	if (efuseType == EFUSE_WIFI)
+		hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
+	else
+		hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
+}
+
+static u16
+hal_EfuseGetCurrentSize_WiFi(
+	PADAPTER	padapter,
+	u8			bPseudoTest)
+{
+#ifdef HAL_EFUSE_MEMORY
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PEFUSE_HAL		pEfuseHal = &pHalData->EfuseHal;
+#endif
+	u16	efuse_addr=0;
+	u16 start_addr = 0; // for debug
+	u8	hoffset=0, hworden=0;
+	u8	efuse_data, word_cnts=0;
+	u32 count = 0; // for debug
+
+
+	if (bPseudoTest)
+	{
+#ifdef HAL_EFUSE_MEMORY
+		efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
+#else
+		efuse_addr = (u16)fakeEfuseUsedBytes;
+#endif
+	}
+	else
+	{
+		rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
+	}
+	start_addr = efuse_addr;
+	DBG_8192C("%s: start_efuse_addr=0x%X\n", __FUNCTION__, efuse_addr);
+
+	// switch bank back to bank 0 for later BT and wifi use.
+	hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
+
+#if 0 // for debug test
+	efuse_OneByteRead(padapter, 0x1FF, &efuse_data, bPseudoTest);
+	DBG_8192C(FUNC_ADPT_FMT ": efuse raw 0x1FF=0x%02X\n",
+		FUNC_ADPT_ARG(padapter), efuse_data);
+	efuse_data = 0xFF;
+#endif // for debug test
+
+	count = 0;
+	while (AVAILABLE_EFUSE_ADDR(efuse_addr))
+	{
+#if 1
+		if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
+		{
+			DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
+			goto error;
+		}
+#else
+		ReadEFuseByte(padapter, efuse_addr, &efuse_data, bPseudoTest);
+#endif
+
+		if (efuse_data == 0xFF) break;
+
+		if ((start_addr != 0) && (efuse_addr == start_addr))
+		{
+			count++;
+			DBG_8192C(FUNC_ADPT_FMT ": [WARNING] efuse raw 0x%X=0x%02X not 0xFF!!(%d times)\n",
+				FUNC_ADPT_ARG(padapter), efuse_addr, efuse_data, count);
+
+			efuse_data = 0xFF;
+			if (count < 4)
+			{
+				// try again!
+
+				if (count > 2)
+				{
+					// try again form address 0
+					efuse_addr = 0;
+					start_addr = 0;
+				}
+
+				continue;
+			}
+
+			goto error;
+		}
+
+		if (EXT_HEADER(efuse_data))
+		{
+			hoffset = GET_HDR_OFFSET_2_0(efuse_data);
+			efuse_addr++;
+			efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
+			if (ALL_WORDS_DISABLED(efuse_data))
+			{
+				continue;
+			}
+
+			hoffset |= ((efuse_data & 0xF0) >> 1);
+			hworden = efuse_data & 0x0F;
+		}
+		else
+		{
+			hoffset = (efuse_data>>4) & 0x0F;
+			hworden = efuse_data & 0x0F;
+		}
+
+		word_cnts = Efuse_CalculateWordCnts(hworden);
+		efuse_addr += (word_cnts*2)+1;
+	}
+
+	if (bPseudoTest)
+	{
+#ifdef HAL_EFUSE_MEMORY
+		pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
+#else
+		fakeEfuseUsedBytes = efuse_addr;
+#endif
+	}
+	else
+	{
+		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
+	}
+	
+	goto exit;
+
+error:
+	// report max size to prevent wirte efuse
+	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest);
+
+exit:
+	DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, efuse_addr);
+
+	return efuse_addr;
+}
+
+static u16
+hal_EfuseGetCurrentSize_BT(
+	PADAPTER	padapter,
+	u8			bPseudoTest)
+{
+#ifdef HAL_EFUSE_MEMORY
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PEFUSE_HAL		pEfuseHal = &pHalData->EfuseHal;
+#endif
+	u16 btusedbytes;
+	u16	efuse_addr;
+	u8	bank, startBank;
+	u8	hoffset=0, hworden=0;
+	u8	efuse_data, word_cnts=0;
+	u16	retU2=0;
+	u8 bContinual = _TRUE;
+
+
+	if (bPseudoTest)
+	{
+#ifdef HAL_EFUSE_MEMORY
+		btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
+#else
+		btusedbytes = fakeBTEfuseUsedBytes;
+#endif
+	}
+	else
+	{
+		btusedbytes = 0;
+		rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&btusedbytes);
+	}
+	efuse_addr = (u16)((btusedbytes%EFUSE_BT_REAL_BANK_CONTENT_LEN));
+	startBank = (u8)(1+(btusedbytes/EFUSE_BT_REAL_BANK_CONTENT_LEN));
+
+	DBG_8192C("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
+
+	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
+
+	for (bank=startBank; bank<3; bank++)
+	{
+		if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
+		{
+			DBG_8192C(KERN_ERR "%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
+			//bank = EFUSE_MAX_BANK;
+			break;
+		}
+
+		// only when bank is switched we have to reset the efuse_addr.
+		if (bank != startBank)
+			efuse_addr = 0;
+#if 1
+
+		while (AVAILABLE_EFUSE_ADDR(efuse_addr))
+		{
+			if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
+			{
+				DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
+				//bank = EFUSE_MAX_BANK;
+				break;
+			}
+			DBG_8192C("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr,efuse_data,bank);
+
+			if (efuse_data == 0xFF) break;
+
+			if (EXT_HEADER(efuse_data))
+			{
+				hoffset = GET_HDR_OFFSET_2_0(efuse_data);
+				efuse_addr++;
+				efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
+				DBG_8192C("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr,efuse_data,bank);
+			
+				if (ALL_WORDS_DISABLED(efuse_data))
+				{
+					efuse_addr++;
+					continue;
+				}
+
+//				hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+				hoffset |= ((efuse_data & 0xF0) >> 1);
+				hworden = efuse_data & 0x0F;
+			}
+			else
+			{
+				hoffset = (efuse_data>>4) & 0x0F;
+				hworden =  efuse_data & 0x0F;
+			}
+
+			DBG_8192C(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",
+				FUNC_ADPT_ARG(padapter), hoffset, hworden);
+
+			word_cnts = Efuse_CalculateWordCnts(hworden);
+			//read next header
+			efuse_addr += (word_cnts*2)+1;
+		}
+#else	
+	while (	bContinual && 
+			efuse_OneByteRead(padapter, efuse_addr ,&efuse_data, bPseudoTest) && 
+			AVAILABLE_EFUSE_ADDR(efuse_addr))
+		{	
+			if(efuse_data!=0xFF)
+			{
+				if((efuse_data&0x1F) == 0x0F)		//extended header
+				{
+					hoffset = efuse_data;
+					efuse_addr++;
+					efuse_OneByteRead(padapter, efuse_addr ,&efuse_data, bPseudoTest);
+					if((efuse_data & 0x0F) == 0x0F)
+					{
+						efuse_addr++;
+						continue;
+					}
+					else
+					{
+						hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+						hworden = efuse_data & 0x0F;
+					}
+				}		
+				else
+				{
+					hoffset = (efuse_data>>4) & 0x0F;
+					hworden =  efuse_data & 0x0F;									
+				}
+				word_cnts = Efuse_CalculateWordCnts(hworden);
+				//read next header							
+				efuse_addr = efuse_addr + (word_cnts*2)+1;						
+			}
+			else
+			{
+				bContinual = _FALSE ;			
+			}
+		}
+#endif			
+	
+
+		// Check if we need to check next bank efuse
+		if (efuse_addr < retU2)
+		{
+			break;// don't need to check next bank.
+		}
+	}
+#if 0
+	retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
+	if (bPseudoTest)
+	{
+#ifdef HAL_EFUSE_MEMORY
+		pEfuseHal->fakeBTEfuseUsedBytes = retU2;
+#else
+		fakeBTEfuseUsedBytes = retU2;
+#endif
+	}
+	else
+	{
+		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&retU2);
+	}
+#else
+	retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN)+efuse_addr;
+	if(bPseudoTest)
+	{
+		pEfuseHal->fakeBTEfuseUsedBytes = retU2;
+		//RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->fakeBTEfuseUsedBytes));
+	}
+	else
+	{
+		pEfuseHal->BTEfuseUsedBytes = retU2;
+		//RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->BTEfuseUsedBytes));
+	}
+#endif
+
+	DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
+	return retU2;
+}
+
+static u16
+Hal_EfuseGetCurrentSize(
+	PADAPTER	pAdapter,
+	u8			efuseType,
+	u8			bPseudoTest)
+{
+	u16	ret = 0;
+
+	if (efuseType == EFUSE_WIFI)
+		ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest);
+	else
+		ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
+
+	return ret;
+}
+
+static u8
+Hal_EfuseWordEnableDataWrite(
+	PADAPTER	padapter,
+	u16			efuse_addr,
+	u8			word_en,
+	u8			*data,
+	u8			bPseudoTest)
+{
+	u16	tmpaddr = 0;
+	u16	start_addr = efuse_addr;
+	u8	badworden = 0x0F;
+	u8	tmpdata[PGPKT_DATA_SIZE];
+
+
+//	DBG_8192C("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en);
+	_rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
+
+	if (!(word_en & BIT(0)))
+	{
+		tmpaddr = start_addr;
+		efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
+		efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
+
+		efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
+		efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
+		if ((data[0]!=tmpdata[0]) || (data[1]!=tmpdata[1])) {
+			badworden &= (~BIT(0));
+		}
+	}
+	if (!(word_en & BIT(1)))
+	{
+		tmpaddr = start_addr;
+		efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
+		efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
+
+		efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
+		efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
+		if ((data[2]!=tmpdata[2]) || (data[3]!=tmpdata[3])) {
+			badworden &= (~BIT(1));
+		}
+	}
+	if (!(word_en & BIT(2)))
+	{
+		tmpaddr = start_addr;
+		efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
+		efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
+
+		efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
+		efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
+		if ((data[4]!=tmpdata[4]) || (data[5]!=tmpdata[5])) {
+			badworden &= (~BIT(2));
+		}
+	}
+	if (!(word_en & BIT(3)))
+	{
+		tmpaddr = start_addr;
+		efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
+		efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
+
+		efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
+		efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
+		if ((data[6]!=tmpdata[6]) || (data[7]!=tmpdata[7])) {
+			badworden &= (~BIT(3));
+		}
+	}
+
+	return badworden;
+}
+
+static s32
+Hal_EfusePgPacketRead(
+	PADAPTER	padapter,
+	u8			offset,
+	u8			*data,
+	u8			bPseudoTest)
+{
+	u8	bDataEmpty = _TRUE;
+	u8	efuse_data, word_cnts=0;
+	u16	efuse_addr=0;
+	u8	hoffset=0, hworden=0;
+	u8	i;
+	u8	max_section = 0;
+	s32	ret;
+
+
+	if (data == NULL)
+		return _FALSE;
+
+	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
+	if (offset > max_section)
+	{
+		DBG_8192C("%s: Packet offset(%d) is illegal(>%d)!\n", __FUNCTION__, offset, max_section);
+		return _FALSE;
+	}
+
+	_rtw_memset(data, 0xFF, PGPKT_DATA_SIZE);
+	ret = _TRUE;
+
+	//
+	// <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP.
+	// Skip dummy parts to prevent unexpected data read from Efuse.
+	// By pass right now. 2009.02.19.
+	//
+	while (AVAILABLE_EFUSE_ADDR(efuse_addr))
+	{
+		if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == _FALSE)
+		{
+			ret = _FALSE;
+			break;
+		}
+
+		if (efuse_data == 0xFF) break;
+
+		if (EXT_HEADER(efuse_data))
+		{
+			hoffset = GET_HDR_OFFSET_2_0(efuse_data);
+			efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
+			if (ALL_WORDS_DISABLED(efuse_data))
+			{
+				DBG_8192C("%s: Error!! All words disabled!\n", __FUNCTION__);
+				continue;
+			}
+
+			hoffset |= ((efuse_data & 0xF0) >> 1);
+			hworden = efuse_data & 0x0F;
+		}
+		else
+		{
+			hoffset = (efuse_data>>4) & 0x0F;
+			hworden =  efuse_data & 0x0F;
+		}
+
+		if (hoffset == offset)
+		{
+			for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
+			{
+				// Check word enable condition in the section
+				if (!(hworden & (0x01<<i)))
+				{
+					//ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
+					efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
+//					DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
+					data[i*2] = efuse_data;
+
+					//ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
+					efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
+//					DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
+					data[(i*2)+1] = efuse_data;
+				}
+			}
+		}
+		else
+		{
+			word_cnts = Efuse_CalculateWordCnts(hworden);
+			efuse_addr += word_cnts*2;
+		}
+	}
+
+	return ret;
+}
+
+static u8
+hal_EfusePgCheckAvailableAddr(
+	PADAPTER	pAdapter,
+	u8			efuseType,
+	u8		bPseudoTest)
+{
+	u16	max_available=0;
+	u16 current_size;
+
+
+	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
+//	DBG_8192C("%s: max_available=%d\n", __FUNCTION__, max_available);
+
+	current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
+	if (current_size >= max_available)
+	{
+		DBG_8192C("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
+		return _FALSE;
+	}
+	return _TRUE;
+}
+
+static void
+hal_EfuseConstructPGPkt(
+	u8 				offset,
+	u8				word_en,
+	u8				*pData,
+	PPGPKT_STRUCT	pTargetPkt)
+{
+	_rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
+	pTargetPkt->offset = offset;
+	pTargetPkt->word_en = word_en;
+	efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
+	pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
+}
+
+#if 0
+static u8
+wordEnMatched(
+	PPGPKT_STRUCT	pTargetPkt,
+	PPGPKT_STRUCT	pCurPkt,
+	u8				*pWden)
+{
+	u8	match_word_en = 0x0F;	// default all words are disabled
+	u8	i;
+
+	// check if the same words are enabled both target and current PG packet
+	if (((pTargetPkt->word_en & BIT(0)) == 0) &&
+		((pCurPkt->word_en & BIT(0)) == 0))
+	{
+		match_word_en &= ~BIT(0);				// enable word 0
+	}
+	if (((pTargetPkt->word_en & BIT(1)) == 0) &&
+		((pCurPkt->word_en & BIT(1)) == 0))
+	{
+		match_word_en &= ~BIT(1);				// enable word 1
+	}
+	if (((pTargetPkt->word_en & BIT(2)) == 0) &&
+		((pCurPkt->word_en & BIT(2)) == 0))
+	{
+		match_word_en &= ~BIT(2);				// enable word 2
+	}
+	if (((pTargetPkt->word_en & BIT(3)) == 0) &&
+		((pCurPkt->word_en & BIT(3)) == 0))
+	{
+		match_word_en &= ~BIT(3);				// enable word 3
+	}
+
+	*pWden = match_word_en;
+
+	if (match_word_en != 0xf)
+		return _TRUE;
+	else
+		return _FALSE;
+}
+
+static u8
+hal_EfuseCheckIfDatafollowed(
+	PADAPTER		pAdapter,
+	u8				word_cnts,
+	u16				startAddr,
+	u8				bPseudoTest)
+{
+	u8 bRet=_FALSE;
+	u8 i, efuse_data;
+
+	for (i=0; i<(word_cnts*2); i++)
+	{
+		if (efuse_OneByteRead(pAdapter, (startAddr+i) ,&efuse_data, bPseudoTest) == _FALSE)
+		{
+			DBG_8192C("%s: efuse_OneByteRead FAIL!!\n", __FUNCTION__);
+			bRet = _TRUE;
+			break;
+		}
+
+		if (efuse_data != 0xFF)
+		{
+			bRet = _TRUE;
+			break;
+		}
+	}
+
+	return bRet;
+}
+#endif
+
+static u8
+hal_EfusePartialWriteCheck(
+	PADAPTER		padapter,
+	u8				efuseType,
+	u16				*pAddr,
+	PPGPKT_STRUCT	pTargetPkt,
+	u8				bPseudoTest)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	PEFUSE_HAL		pEfuseHal = &pHalData->EfuseHal;
+	u8	bRet=_FALSE;
+	u16	startAddr=0, efuse_max_available_len=0, efuse_max=0;
+	u8	efuse_data=0;
+#if 0
+	u8	i, cur_header=0;
+	u8	new_wden=0, matched_wden=0, badworden=0;
+	PGPKT_STRUCT	curPkt;
+#endif
+
+
+	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
+	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
+
+	if (efuseType == EFUSE_WIFI)
+	{
+		if (bPseudoTest)
+		{
+#ifdef HAL_EFUSE_MEMORY
+			startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
+#else
+			startAddr = (u16)fakeEfuseUsedBytes;
+#endif
+		}
+		else
+		{
+			rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&startAddr);
+		}
+	}
+	else
+	{
+		if (bPseudoTest)
+		{
+#ifdef HAL_EFUSE_MEMORY
+			startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
+#else
+			startAddr = (u16)fakeBTEfuseUsedBytes;
+#endif
+		}
+		else
+		{
+			rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&startAddr);
+		}
+	}
+	startAddr %= efuse_max;
+	DBG_8192C("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
+
+	while (1)
+	{
+		if (startAddr >= efuse_max_available_len)
+		{
+			bRet = _FALSE;
+			DBG_8192C("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
+				__FUNCTION__, startAddr, efuse_max_available_len);
+			break;
+		}
+
+		if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data!=0xFF))
+		{
+#if 1
+			bRet = _FALSE;
+			DBG_8192C("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
+				__FUNCTION__, startAddr, efuse_data);
+			break;
+#else
+			if (EXT_HEADER(efuse_data))
+			{
+				cur_header = efuse_data;
+				startAddr++;
+				efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
+				if (ALL_WORDS_DISABLED(efuse_data))
+				{
+					DBG_8192C("%s: Error condition, all words disabled!", __FUNCTION__);
+					bRet = _FALSE;
+					break;
+				}
+				else
+				{
+					curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+					curPkt.word_en = efuse_data & 0x0F;
+				}
+			}
+			else
+			{
+				cur_header  =  efuse_data;
+				curPkt.offset = (cur_header>>4) & 0x0F;
+				curPkt.word_en = cur_header & 0x0F;
+			}
+
+			curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
+			// if same header is found but no data followed
+			// write some part of data followed by the header.
+			if ((curPkt.offset == pTargetPkt->offset) &&
+				(hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr+1, bPseudoTest) == _FALSE) &&
+				wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == _TRUE)
+			{
+				DBG_8192C("%s: Need to partial write data by the previous wrote header\n", __FUNCTION__);
+				// Here to write partial data
+				badworden = Efuse_WordEnableDataWrite(padapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
+				if (badworden != 0x0F)
+				{
+					u32	PgWriteSuccess=0;
+					// if write fail on some words, write these bad words again
+					if (efuseType == EFUSE_WIFI)
+						PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
+					else
+						PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
+
+					if (!PgWriteSuccess)
+					{
+						bRet = _FALSE;	// write fail, return
+						break;
+					}
+				}
+				// partial write ok, update the target packet for later use
+				for (i=0; i<4; i++)
+				{
+					if ((matched_wden & (0x1<<i)) == 0)	// this word has been written
+					{
+						pTargetPkt->word_en |= (0x1<<i);	// disable the word
+					}
+				}
+				pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
+			}
+			// read from next header
+			startAddr = startAddr + (curPkt.word_cnts*2) + 1;
+#endif
+		}
+		else
+		{
+			// not used header, 0xff
+			*pAddr = startAddr;
+//			DBG_8192C("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr));
+			bRet = _TRUE;
+			break;
+		}
+	}
+
+	return bRet;
+}
+
+static u8
+hal_EfusePgPacketWrite1ByteHeader(
+	PADAPTER		pAdapter,
+	u8				efuseType,
+	u16				*pAddr,
+	PPGPKT_STRUCT	pTargetPkt,
+	u8				bPseudoTest)
+{
+	u8	bRet=_FALSE;
+	u8	pg_header=0, tmp_header=0;
+	u16	efuse_addr=*pAddr;
+	u8	repeatcnt=0;
+
+
+//	DBG_8192C("%s\n", __FUNCTION__);
+	pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
+
+	do {
+		efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
+		efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
+		if (tmp_header != 0xFF) break;
+		if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
+		{
+			DBG_8192C("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
+			return _FALSE;
+		}
+	} while (1);
+
+	if (tmp_header != pg_header)
+	{
+		DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
+		return _FALSE;
+	}
+
+	*pAddr = efuse_addr;
+
+	return _TRUE;
+}
+
+static u8
+hal_EfusePgPacketWrite2ByteHeader(
+	PADAPTER		padapter,
+	u8				efuseType,
+	u16				*pAddr,
+	PPGPKT_STRUCT	pTargetPkt,
+	u8				bPseudoTest)
+{
+	u16	efuse_addr, efuse_max_available_len=0;
+	u8	pg_header=0, tmp_header=0;
+	u8	repeatcnt=0;
+
+
+//	DBG_8192C("%s\n", __FUNCTION__);
+	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
+
+	efuse_addr = *pAddr;
+	if (efuse_addr >= efuse_max_available_len)
+	{
+		DBG_8192C("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
+		return _FALSE;
+	}
+
+	pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
+//	DBG_8192C("%s: pg_header=0x%x\n", __FUNCTION__, pg_header);
+
+	do {
+		efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
+		efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
+		if (tmp_header != 0xFF) break;
+		if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
+		{
+			DBG_8192C("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
+			return _FALSE;
+		}
+	} while (1);
+
+	if (tmp_header != pg_header)
+	{
+		DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
+		return _FALSE;
+	}
+
+	// to write ext_header
+	efuse_addr++;
+	pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
+
+	do {
+		efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
+		efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
+		if (tmp_header != 0xFF) break;
+		if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
+		{
+			DBG_8192C("%s: Repeat over limit for ext_header!!\n", __FUNCTION__);
+			return _FALSE;
+		}
+	} while (1);
+
+	if (tmp_header != pg_header)	//offset PG fail
+	{
+		DBG_8192C(KERN_ERR "%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
+		return _FALSE;
+	}
+
+	*pAddr = efuse_addr;
+
+	return _TRUE;
+}
+
+static u8
+hal_EfusePgPacketWriteHeader(
+	PADAPTER		padapter,
+	u8				efuseType,
+	u16				*pAddr,
+	PPGPKT_STRUCT	pTargetPkt,
+	u8				bPseudoTest)
+{
+	u8 bRet=_FALSE;
+
+	if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
+	{
+		bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
+	}
+	else
+	{
+		bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
+	}
+
+	return bRet;
+}
+
+static u8
+hal_EfusePgPacketWriteData(
+	PADAPTER		pAdapter,
+	u8				efuseType,
+	u16				*pAddr,
+	PPGPKT_STRUCT	pTargetPkt,
+	u8				bPseudoTest)
+{
+	u16	efuse_addr;
+	u8	badworden;
+
+
+	efuse_addr = *pAddr;
+	badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
+	if (badworden != 0x0F)
+	{
+		DBG_8192C("%s: Fail!!\n", __FUNCTION__);
+		return _FALSE;
+	}
+
+//	DBG_8192C("%s: ok\n", __FUNCTION__);
+	return _TRUE;
+}
+
+static s32
+Hal_EfusePgPacketWrite(
+	PADAPTER	padapter,
+	u8 			offset,
+	u8			word_en,
+	u8			*pData,
+	u8			bPseudoTest)
+{
+	PGPKT_STRUCT targetPkt;
+	u16 startAddr=0;
+	u8 efuseType=EFUSE_WIFI;
+
+	if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
+		return _FALSE;
+
+	hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
+
+	if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+		return _FALSE;
+
+	if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+		return _FALSE;
+
+	if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+		return _FALSE;
+
+	return _TRUE;
+}
+
+static u8
+Hal_EfusePgPacketWrite_BT(
+	PADAPTER	pAdapter,
+	u8 			offset,
+	u8			word_en,
+	u8			*pData,
+	u8			bPseudoTest)
+{
+	PGPKT_STRUCT targetPkt;
+	u16 startAddr=0;
+	u8 efuseType=EFUSE_BT;
+
+	if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
+		return _FALSE;
+
+	hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
+
+	if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+		return _FALSE;
+
+	if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+		return _FALSE;
+
+	if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+		return _FALSE;
+
+	return _TRUE;
+}
+
+
+static void read_chip_version_8703b(PADAPTER padapter)
+{
+	u32				value32;
+	HAL_DATA_TYPE	*pHalData;
+	pHalData = GET_HAL_DATA(padapter);
+
+	value32 = rtw_read32(padapter, REG_SYS_CFG);
+	pHalData->VersionID.ICType = CHIP_8703B;
+	pHalData->VersionID.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
+	pHalData->VersionID.RFType = RF_TYPE_1T1R ;
+	pHalData->VersionID.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
+	pHalData->VersionID.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; // IC version (CUT)
+
+	// For regulator mode. by tynli. 2011.01.14
+	pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
+
+	value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
+	pHalData->VersionID.ROMVer = ((value32 & RF_RL_ID) >> 20);	// ROM code version.
+
+	// For multi-function consideration. Added by Roger, 2010.10.06.
+	pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
+	value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
+	pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
+	pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
+	pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
+	pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
+
+	rtw_hal_config_rftype(padapter);
+
+/*	// mark for chage to use efuse
+	if( IS_B_CUT(pHalData->VersionID) || IS_C_CUT(pHalData->VersionID))
+	{
+		MSG_8192C(" IS_B/C_CUT SWR up 1 level !!!!!!!!!!!!!!!!!\n");
+		PHY_SetMacReg(padapter, 0x14, BIT23|BIT22|BIT21|BIT20, 0x5); //MAC reg 0x14[23:20] = 4b'0101 (SWR 1.220V)
+	}else if ( IS_D_CUT(pHalData->VersionID))
+	{
+		MSG_8192C(" IS_D_CUT SKIP SWR !!!!!!!!!!!!!!!!!\n");
+	}
+*/
+
+#if 1
+	dump_chip_info(pHalData->VersionID);
+#endif
+
+}
+
+
+void rtl8703b_InitBeaconParameters(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	u16 val16;
+	u8 val8;
+
+
+	val8 = DIS_TSF_UDT;
+	val16 = val8 | (val8 << 8); // port0 and port1
+#ifdef CONFIG_BT_COEXIST
+	// Enable prot0 beacon function for PSTDMA
+	val16 |= EN_BCN_FUNCTION;
+#endif
+	rtw_write16(padapter, REG_BCN_CTRL, val16);
+
+	// TODO: Remove these magic number
+	rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);// ms
+	// Firmware will control REG_DRVERLYINT when power saving is enable,
+	// so don't set this register on STA mode.
+	if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _FALSE)
+		rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8703B); // 5ms
+	rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8703B); // 2ms
+
+	// Suggested by designer timchen. Change beacon AIFS to the largest number
+	// beacause test chip does not contension before sending beacon. by tynli. 2009.11.03
+	rtw_write16(padapter, REG_BCNTCFG, 0x660F);
+	
+	pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL);
+	pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE); 
+	pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2);
+	pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT+2);
+	pHalData->RegCR_1 = rtw_read8(padapter, REG_CR+1);
+}
+
+void rtl8703b_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode)
+{
+#ifdef CONFIG_ADHOC_WORKAROUND_SETTING
+	rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
+#else
+	//rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10));
+#endif
+}
+
+void	_InitBurstPktLen_8703BS(PADAPTER Adapter)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+
+	rtw_write8(Adapter, 0x4c7,rtw_read8(Adapter, 0x4c7)|BIT(7)); //enable single pkt ampdu
+	rtw_write8(Adapter, REG_RX_PKT_LIMIT_8703B, 0x18);		//for VHT packet length 11K
+	rtw_write8(Adapter, REG_MAX_AGGR_NUM_8703B, 0x1F);
+	rtw_write8(Adapter, REG_PIFS_8703B, 0x00);
+	rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8703B, rtw_read8(Adapter, REG_FWHW_TXQ_CTRL)&(~BIT(7)));
+	if(pHalData->AMPDUBurstMode)
+	{
+		rtw_write8(Adapter,REG_AMPDU_BURST_MODE_8703B,  0x5F);
+	}
+	rtw_write8(Adapter, REG_AMPDU_MAX_TIME_8703B, 0x70);
+
+	// ARFB table 9 for 11ac 5G 2SS
+	rtw_write32(Adapter, REG_ARFR0_8703B, 0x00000010);
+	if(IS_NORMAL_CHIP(pHalData->VersionID))
+		rtw_write32(Adapter, REG_ARFR0_8703B+4, 0xfffff000);
+	else
+		rtw_write32(Adapter, REG_ARFR0_8703B+4, 0x3e0ff000);
+
+	// ARFB table 10 for 11ac 5G 1SS
+	rtw_write32(Adapter, REG_ARFR1_8703B, 0x00000010);
+	rtw_write32(Adapter, REG_ARFR1_8703B+4, 0x003ff000);
+}
+
+void _InitLTECoex_8703BS(PADAPTER Adapter)
+{
+	// LTE COEX setting
+	rtw_write16(Adapter, REG_LTECOEX_WRITE_DATA, 0x7700);
+	rtw_write32(Adapter, REG_LTECOEX_CTRL, 0xc0020038);
+	rtw_write8(Adapter, 0x73, 0x04);
+}
+
+void _InitMacAPLLSetting_8703B(PADAPTER Adapter)
+{
+	u16 RegValue;
+
+	RegValue = rtw_read16(Adapter, REG_AFE_CTRL_4_8703B);
+	RegValue |= BIT(4);
+	RegValue |= BIT(15);
+	rtw_write16(Adapter, REG_AFE_CTRL_4_8703B, RegValue);
+}
+
+static void ResumeTxBeacon(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+
+	// 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
+	// which should be read from register to a global variable.
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
+
+	pHalData->RegFwHwTxQCtrl |= BIT(6);
+	rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
+	rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
+	pHalData->RegReg542 |= BIT(0);
+	rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
+}
+
+static void StopTxBeacon(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+
+	// 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
+	// which should be read from register to a global variable.
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
+
+	pHalData->RegFwHwTxQCtrl &= ~BIT(6);
+	rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
+	rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
+	pHalData->RegReg542 &= ~BIT(0);
+	rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
+
+	CheckFwRsvdPageContent(padapter);  // 2010.06.23. Added by tynli.
+}
+
+static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked)
+{
+	rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
+	rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
+}
+
+static void rtl8703b_SetBeaconRelatedRegisters(PADAPTER padapter)
+{
+	u8 val8;
+	u32 value32;
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+	u32 bcn_ctrl_reg;
+
+	//reset TSF, enable update TSF, correcting TSF On Beacon
+
+	//REG_BCN_INTERVAL
+	//REG_BCNDMATIM
+	//REG_ATIMWND
+	//REG_TBTT_PROHIBIT
+	//REG_DRVERLYINT
+	//REG_BCN_MAX_ERR
+	//REG_BCNTCFG //(0x510)
+	//REG_DUAL_TSF_RST
+	//REG_BCN_CTRL //(0x550)
+
+
+	bcn_ctrl_reg = REG_BCN_CTRL;
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->iface_type == IFACE_PORT1)
+		bcn_ctrl_reg = REG_BCN_CTRL_1;
+#endif
+
+	//
+	// ATIM window
+	//
+	rtw_write16(padapter, REG_ATIMWND, 2);
+
+	//
+	// Beacon interval (in unit of TU).
+	//
+	rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
+
+	rtl8703b_InitBeaconParameters(padapter);
+
+	rtw_write8(padapter, REG_SLOT, 0x09);
+
+	//
+	// Reset TSF Timer to zero, added by Roger. 2008.06.24
+	//
+	value32 = rtw_read32(padapter, REG_TCR);
+	value32 &= ~TSFRST;
+	rtw_write32(padapter, REG_TCR, value32);
+
+	value32 |= TSFRST;
+	rtw_write32(padapter, REG_TCR, value32);
+
+	// NOTE: Fix test chip's bug (about contention windows's randomness)
+	if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == _TRUE)
+	{
+		rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
+		rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
+	}
+
+	_BeaconFunctionEnable(padapter, _TRUE, _TRUE);
+
+	ResumeTxBeacon(padapter);
+	val8 = rtw_read8(padapter, bcn_ctrl_reg);
+	val8 |= DIS_BCNQ_SUB;
+	rtw_write8(padapter, bcn_ctrl_reg, val8);
+}
+
+void hal_notch_filter_8703b(_adapter *adapter, bool enable)
+{
+	if (enable) {
+		DBG_871X("Enable notch filter\n");
+		rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
+	} else {
+		DBG_871X("Disable notch filter\n");
+		rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
+	}
+}
+
+u8 rtl8703b_MRateIdxToARFRId(PADAPTER padapter, u8 rate_idx)
+{
+	u8 ret = 0;
+	RT_RF_TYPE_DEF_E rftype = (RT_RF_TYPE_DEF_E)GET_RF_TYPE(padapter);
+	switch(rate_idx){
+
+	case RATR_INX_WIRELESS_NGB:
+		if(rftype == RF_1T1R)
+			ret = 1;
+		else 
+			ret = 0;
+		break;
+
+	case RATR_INX_WIRELESS_N:
+	case RATR_INX_WIRELESS_NG:
+		if(rftype == RF_1T1R)
+			ret = 5;
+		else
+			ret = 4;
+		break;
+
+	case RATR_INX_WIRELESS_NB:
+		if(rftype == 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(padapter->mlmeextpriv.cur_wireless_mode & WIRELESS_11BG_24N)
+			ret = 6;
+		else
+			ret = 7;
+		break;
+	case RATR_INX_WIRELESS_AC_N:
+		if(rftype == RF_1T1R)// || padapter->MgntInfo.VHTHighestOperaRate <= MGN_VHT1SS_MCS9)
+			ret = 10;
+		else
+			ret = 9;
+		break;
+
+	default:
+		ret = 0;
+		break;
+	}	
+
+	return ret;
+}
+
+void UpdateHalRAMask8703B(PADAPTER padapter, u32 mac_id, u8 rssi_level)
+{
+	u32	mask,rate_bitmap;
+	u8	shortGIrate = _FALSE;
+	struct sta_info	*psta;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+
+	DBG_871X("%s(): mac_id=%d rssi_level=%d\n", __func__, mac_id, rssi_level);
+
+	if (mac_id >= NUM_STA) //CAM_SIZE
+	{
+		return;
+	}
+
+	psta = pmlmeinfo->FW_sta_info[mac_id].psta;
+	if(psta == NULL)
+	{
+		return;
+	}
+
+	shortGIrate = query_ra_short_GI(psta);
+
+	mask = psta->ra_mask;
+
+	rate_bitmap = 0xffffffff;					
+	rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv,mac_id,mask,rssi_level);
+	DBG_871X("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
+			__FUNCTION__,mac_id,psta->wireless_mode,mask,rssi_level,rate_bitmap);
+
+	mask &= rate_bitmap;
+
+#ifdef CONFIG_BT_COEXIST
+	rate_bitmap = rtw_btcoex_GetRaMask(padapter);
+	mask &= ~rate_bitmap;
+#endif // CONFIG_BT_COEXIST
+
+#ifdef CONFIG_CMCC_TEST
+#ifdef CONFIG_BT_COEXIST
+	if(pmlmeext->cur_wireless_mode & WIRELESS_11G) {
+		if (mac_id == 0) {
+			DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask);
+			//mask &=0xffffffc0; //disable CCK & <12M OFDM rate for 11G mode for CMCC
+			mask &=0xffffff00; //disable CCK & <24M OFDM rate for 11G mode for CMCC
+			DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask);
+		}
+	}
+#endif
+#endif
+
+	if(pHalData->fw_ractrl == _TRUE)
+	{
+		rtl8703b_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, shortGIrate, mask);
+	}
+
+	//set correct initial date rate for each mac_id
+	pHalData->INIDATA_RATE[mac_id] = psta->init_rate;
+	DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x init_rate=0x%x\n", __func__, mac_id, psta->raid, psta->bw_mode, mask, psta->init_rate);
+}
+
+//
+// Description: In normal chip, we should send some packet to Hw which will be used by Fw
+//			in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
+//			Fw can tell Hw to send these packet derectly.
+// Added by tynli. 2009.10.15.
+//
+//type1:pspoll, type2:null
+void rtl8703b_fill_fake_txdesc(
+	PADAPTER	padapter,
+	u8*			pDesc,
+	u32			BufferLen,
+	u8			IsPsPoll,
+	u8			IsBTQosNull,
+	u8			bDataFrame)
+{
+	// Clear all status
+	_rtw_memset(pDesc, 0, TXDESC_SIZE);
+
+	SET_TX_DESC_FIRST_SEG_8703B(pDesc, 1); //bFirstSeg;
+	SET_TX_DESC_LAST_SEG_8703B(pDesc, 1); //bLastSeg;
+
+	SET_TX_DESC_OFFSET_8703B(pDesc, 0x28); // Offset = 32
+
+	SET_TX_DESC_PKT_SIZE_8703B(pDesc, BufferLen); // Buffer size + command header
+	SET_TX_DESC_QUEUE_SEL_8703B(pDesc, QSLT_MGNT); // Fixed queue of Mgnt queue
+
+	// Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
+	if (_TRUE == IsPsPoll)
+	{
+		SET_TX_DESC_NAV_USE_HDR_8703B(pDesc, 1);
+	}
+	else
+	{
+		SET_TX_DESC_HWSEQ_EN_8703B(pDesc, 1); // Hw set sequence number
+		SET_TX_DESC_HWSEQ_SEL_8703B(pDesc, 0);
+	}
+
+	if (_TRUE ==IsBTQosNull)
+	{
+		SET_TX_DESC_BT_INT_8703B(pDesc, 1);
+	}
+
+	SET_TX_DESC_USE_RATE_8703B(pDesc, 1); // use data rate which is set by Sw
+	SET_TX_DESC_OWN_8703B((pu1Byte)pDesc, 1);
+
+	SET_TX_DESC_TX_RATE_8703B(pDesc, DESC8703B_RATE1M);
+
+	//
+	// Encrypt the data frame if under security mode excepct null data. Suggested by CCW.
+	//
+	if (_TRUE ==bDataFrame)
+	{
+		u32 EncAlg;
+
+		EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
+		switch (EncAlg)
+		{
+			case _NO_PRIVACY_:
+				SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x0); 
+				break;
+			case _WEP40_:
+			case _WEP104_:
+			case _TKIP_:
+				SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x1); 
+				break;
+			case _SMS4_:
+				SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x2); 
+				break;
+			case _AES_:
+				SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x3);
+				break;
+			default:
+				SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x0); 
+				break;	 
+		}
+	}
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+	// USB interface drop packet if the checksum of descriptor isn't correct.
+	// Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
+	rtl8703b_cal_txdesc_chksum((struct tx_desc*)pDesc);
+#endif
+}
+
+void rtl8703b_set_hal_ops(struct hal_ops *pHalFunc)
+{
+	pHalFunc->dm_init = &rtl8703b_init_dm_priv;
+	pHalFunc->dm_deinit = &rtl8703b_deinit_dm_priv;
+
+	pHalFunc->read_chip_version = read_chip_version_8703b;
+
+	pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8703B;
+	pHalFunc->set_bwmode_handler = &PHY_SetBWMode8703B;
+	pHalFunc->set_channel_handler = &PHY_SwChnl8703B;
+	pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8703B;
+
+	pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8703B;
+	pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8703B;
+
+	pHalFunc->hal_dm_watchdog = &rtl8703b_HalDmWatchDog;
+#ifdef CONFIG_LPS_LCLK_WD_TIMER
+	pHalFunc->hal_dm_watchdog_in_lps = &rtl8703b_HalDmWatchDog_in_LPS;
+#endif
+
+#ifdef CONFIG_C2H_PACKET_EN
+	pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8703B;
+#endif // CONFIG_C2H_PACKET_EN
+	
+	pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8703b_SetBeaconRelatedRegisters;
+
+	pHalFunc->Add_RateATid = &rtl8703b_Add_RateATid;
+
+	pHalFunc->run_thread= &rtl8703b_start_thread;
+	pHalFunc->cancel_thread= &rtl8703b_stop_thread;
+
+	pHalFunc->read_bbreg = &PHY_QueryBBReg_8703B;
+	pHalFunc->write_bbreg = &PHY_SetBBReg_8703B;
+	pHalFunc->read_rfreg = &PHY_QueryRFReg_8703B;
+	pHalFunc->write_rfreg = &PHY_SetRFReg_8703B;
+
+	// Efuse related function
+	pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch;
+	pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
+	pHalFunc->ReadEFuse = &Hal_ReadEFuse;
+	pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
+	pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
+	pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
+	pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
+	pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
+	pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
+
+#ifdef DBG_CONFIG_ERROR_DETECT
+	pHalFunc->sreset_init_value = &sreset_init_value;
+	pHalFunc->sreset_reset_value = &sreset_reset_value;
+	pHalFunc->silentreset = &sreset_reset;
+	pHalFunc->sreset_xmit_status_check = &rtl8703b_sreset_xmit_status_check;
+	pHalFunc->sreset_linked_status_check  = &rtl8703b_sreset_linked_status_check;
+	pHalFunc->sreset_get_wifi_status  = &sreset_get_wifi_status;
+	pHalFunc->sreset_inprogress= &sreset_inprogress;
+#endif
+	pHalFunc->GetHalODMVarHandler = GetHalODMVar;
+	pHalFunc->SetHalODMVarHandler = SetHalODMVar;
+
+#ifdef CONFIG_XMIT_THREAD_MODE
+	pHalFunc->xmit_thread_handler = &hal_xmit_handler;
+#endif
+	pHalFunc->hal_notch_filter = &hal_notch_filter_8703b;
+
+	pHalFunc->c2h_handler = c2h_handler_8703b;
+	pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8703b;
+
+	pHalFunc->fill_h2c_cmd = &FillH2CCmd8703B;
+	pHalFunc->fill_fake_txdesc = &rtl8703b_fill_fake_txdesc;
+	pHalFunc->fw_dl = &rtl8703b_FirmwareDownload;
+	pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8703B;
+}
+
+void rtl8703b_InitAntenna_Selection(PADAPTER padapter)
+{
+#if 0
+	PHAL_DATA_TYPE pHalData;
+	u8 val;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+#if 0
+	val = rtw_read8(padapter, REG_LEDCFG2);
+	// Let 8051 take control antenna settting
+	val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
+	rtw_write8(padapter, REG_LEDCFG2, val);
+#else
+		// TODO: <20130114, Kordan> The following setting is only for DPDT and Fixed board type.
+	// TODO:  A better solution is configure it according EFUSE during the run-time. 
+	PHY_SetMacReg(padapter, 0x64, BIT20, 0x0);		   //0x66[4]=0		
+	PHY_SetMacReg(padapter, 0x64, BIT24, 0x0);		   //0x66[8]=0
+	PHY_SetMacReg(padapter, 0x40, BIT4, 0x0);		   //0x40[4]=0		
+	PHY_SetMacReg(padapter, 0x40, BIT3, 0x1);		   //0x40[3]=1		
+	PHY_SetMacReg(padapter, 0x4C, BIT24, 0x1);   	   //0x4C[24:23]=10
+	PHY_SetMacReg(padapter, 0x4C, BIT23, 0x0);   	   //0x4C[24:23]=10	
+	PHY_SetBBReg(padapter, 0x944, BIT1|BIT0, 0x3);     //0x944[1:0]=11	
+	PHY_SetBBReg(padapter, 0x930, bMaskByte0, 0x77);   //0x930[7:0]=77	  
+	PHY_SetMacReg(padapter, 0x38, BIT11, 0x1); 	       //0x38[11]=1 
+#endif
+#endif
+}
+
+void rtl8703b_CheckAntenna_Selection(PADAPTER padapter)
+{
+#if 0
+	PHAL_DATA_TYPE pHalData;
+	u8 val;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	val = rtw_read8(padapter, REG_LEDCFG2);
+	// Let 8051 take control antenna settting
+	if(!(val &BIT(7))){
+		val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
+		rtw_write8(padapter, REG_LEDCFG2, val);
+	}
+#endif
+}
+void rtl8703b_DeinitAntenna_Selection(PADAPTER padapter)
+{
+#if 0
+	PHAL_DATA_TYPE pHalData;
+	u8 val;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	val = rtw_read8(padapter, REG_LEDCFG2);
+	// Let 8051 take control antenna settting
+	val &= ~BIT(7); // DPDT_SEL_EN, clear 0x4C[23]
+	rtw_write8(padapter, REG_LEDCFG2, val);
+#endif
+}
+
+void init_hal_spec_8703b(_adapter *adapter)
+{
+	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+
+	hal_spec->macid_num = MACID_NUM_8703B;
+	hal_spec->sec_cam_ent_num = SEC_CAM_ENT_NUM_8703B;
+	hal_spec->sec_cap = 0;
+	hal_spec->nss_num = NSS_NUM_8703B;
+	hal_spec->band_cap = BAND_CAP_8703B;
+	hal_spec->bw_cap = BW_CAP_8703B;
+	hal_spec->proto_cap = PROTO_CAP_8703B;
+
+	hal_spec->wl_func = 0
+					| WL_FUNC_P2P
+					| WL_FUNC_MIRACAST
+					| WL_FUNC_TDLS
+					;
+}
+
+void rtl8703b_init_default_value(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	u8 i;
+	pHalData = GET_HAL_DATA(padapter);
+
+	padapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
+
+	// init default value
+	pHalData->fw_ractrl = _FALSE;
+	if (!adapter_to_pwrctl(padapter)->bkeepfwalive)
+		pHalData->LastHMEBoxNum = 0;
+
+	//init phydm default value
+	pHalData->bIQKInitialized = _FALSE;
+	pHalData->odmpriv.RFCalibrateInfo.TM_Trigger = 0;//for IQK
+	pHalData->odmpriv.RFCalibrateInfo.ThermalValue_HP_index = 0;
+	for (i=0; i<HP_THERMAL_NUM; i++)
+		pHalData->odmpriv.RFCalibrateInfo.ThermalValue_HP[i] = 0;
+
+	// init Efuse variables
+	pHalData->EfuseUsedBytes = 0;
+	pHalData->EfuseUsedPercentage = 0;
+#ifdef HAL_EFUSE_MEMORY
+	pHalData->EfuseHal.fakeEfuseBank = 0;
+	pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
+	_rtw_memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
+	_rtw_memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
+	_rtw_memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
+	pHalData->EfuseHal.BTEfuseUsedBytes = 0;
+	pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
+	_rtw_memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
+	_rtw_memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
+	_rtw_memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
+	pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
+	_rtw_memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
+	_rtw_memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
+	_rtw_memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
+#endif
+}
+
+u8 GetEEPROMSize8703B(PADAPTER padapter)
+{
+	u8 size = 0;
+	u32	cr;
+
+	cr = rtw_read16(padapter, REG_9346CR);
+	// 6: EEPROM used is 93C46, 4: boot from E-Fuse.
+	size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
+
+	MSG_8192C("EEPROM type is %s\n", size==4 ? "E-FUSE" : "93C46");
+
+	return size;
+}
+
+//-------------------------------------------------------------------------
+//
+// LLT R/W/Init function
+//
+//-------------------------------------------------------------------------
+s32 rtl8703b_InitLLTTable(PADAPTER padapter)
+{
+	u32 start, passing_time;
+	u32 val32;
+	s32 ret;
+
+
+	ret = _FAIL;
+
+	val32 = rtw_read32(padapter, REG_AUTO_LLT);
+	val32 |= BIT_AUTO_INIT_LLT;
+	rtw_write32(padapter, REG_AUTO_LLT, val32);
+
+	start = rtw_get_current_time();
+
+	do {
+		val32 = rtw_read32(padapter, REG_AUTO_LLT);
+		if (!(val32 & BIT_AUTO_INIT_LLT))
+		{
+			ret = _SUCCESS;
+			break;
+		}
+
+		passing_time = rtw_get_passing_time_ms(start);
+		if (passing_time > 1000)
+		{
+			DBG_8192C("%s: FAIL!! REG_AUTO_LLT(0x%X)=%08x\n",
+				__FUNCTION__, REG_AUTO_LLT, val32);
+			break;
+		}
+
+		rtw_usleep_os(2);
+	} while(1);
+
+	return ret;
+}
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+void _DisableGPIO(PADAPTER	padapter)
+{
+/***************************************
+j. GPIO_PIN_CTRL 0x44[31:0]=0x000		//
+k.Value = GPIO_PIN_CTRL[7:0]
+l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); //write external PIN level
+m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
+n. LEDCFG 0x4C[15:0] = 0x8080
+***************************************/
+	u8	value8;
+	u16	value16;
+	u32	value32;
+	u32	u4bTmp;
+
+
+	//1. Disable GPIO[7:0]
+	rtw_write16(padapter, REG_GPIO_PIN_CTRL+2, 0x0000);
+	value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
+	u4bTmp = value32 & 0x000000FF;
+	value32 |= ((u4bTmp<<8) | 0x00FF0000);
+	rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
+
+	
+		//2. Disable GPIO[10:8]
+		rtw_write8(padapter, REG_MAC_PINMUX_CFG, 0x00);
+		value16 = rtw_read16(padapter, REG_GPIO_IO_SEL) & 0xFF0F;
+		value8 = (u8) (value16&0x000F);
+		value16 |= ((value8<<4) | 0x0780);
+		rtw_write16(padapter, REG_GPIO_IO_SEL, value16);
+	
+
+	//3. Disable LED0 & 1
+		rtw_write16(padapter, REG_LEDCFG0, 0x8080);
+	
+//	RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable GPIO and LED.\n"));
+} //end of _DisableGPIO()
+
+void _DisableRFAFEAndResetBB8703B(PADAPTER padapter)
+{
+/**************************************
+a.	TXPAUSE 0x522[7:0] = 0xFF             //Pause MAC TX queue
+b.	RF path 0 offset 0x00 = 0x00            // disable RF
+c. 	APSD_CTRL 0x600[7:0] = 0x40
+d.	SYS_FUNC_EN 0x02[7:0] = 0x16		//reset BB state machine
+e.	SYS_FUNC_EN 0x02[7:0] = 0x14		//reset BB state machine
+***************************************/
+    	u8 eRFPath = 0, value8 = 0;
+
+	rtw_write8(padapter, REG_TXPAUSE, 0xFF);
+
+	PHY_SetRFReg(padapter, (RF_PATH)eRFPath, 0x0, bMaskByte0, 0x0);
+
+	value8 |= APSDOFF;
+	rtw_write8(padapter, REG_APSD_CTRL, value8);//0x40
+
+	// Set BB reset at first
+	value8 = 0 ;
+	value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
+	rtw_write8(padapter, REG_SYS_FUNC_EN, value8 );//0x16
+
+	// Set global reset.
+	value8 &= ~FEN_BB_GLB_RSTn;
+	rtw_write8(padapter, REG_SYS_FUNC_EN, value8); //0x14
+
+	// 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode.
+
+//	RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n"));
+}
+
+void _DisableRFAFEAndResetBB(PADAPTER padapter)
+{
+	_DisableRFAFEAndResetBB8703B(padapter);
+}
+
+void _ResetDigitalProcedure1_8703B(PADAPTER padapter, BOOLEAN bWithoutHWSM)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+	if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20))
+	{
+		#if 0
+/*****************************
+		f.	SYS_FUNC_EN 0x03[7:0]=0x54		// reset MAC register, DCORE
+		g.	MCUFWDL 0x80[7:0]=0				// reset MCU ready status
+******************************/
+	u32	value32 = 0;
+		rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54);
+		rtw_write8(padapter, REG_MCUFWDL, 0);
+		#else
+		/*****************************
+		f.	MCUFWDL 0x80[7:0]=0				// reset MCU ready status
+		g.	SYS_FUNC_EN 0x02[10]= 0			// reset MCU register, (8051 reset)
+		h.	SYS_FUNC_EN 0x02[15-12]= 5		// reset MAC register, DCORE
+		i.     SYS_FUNC_EN 0x02[10]= 1			// enable MCU register, (8051 enable)
+		******************************/
+			u16 valu16 = 0;
+			rtw_write8(padapter, REG_MCUFWDL, 0);
+
+			valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
+			rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));//reset MCU ,8051
+
+			valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN)&0x0FFF;
+			rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 |(FEN_HWPDN|FEN_ELDR)));//reset MAC
+
+			valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
+			rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));//enable MCU ,8051
+		#endif
+	}
+	else
+	{
+		u8 retry_cnts = 0;
+
+		// 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to
+		// enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because
+		// we will init FW when power on again.
+		//if(!pDevice->RegUsbSS)
+		{	// If we want to SS mode, we can not reset 8051.
+			if(rtw_read8(padapter, REG_MCUFWDL) & BIT1)
+			{ //IF fw in RAM code, do reset
+
+
+				if(padapter->bFWReady)
+				{
+					// 2010/08/25 MH Accordign to RD alfred's suggestion, we need to disable other
+					// HRCV INT to influence 8051 reset.
+					rtw_write8(padapter, REG_FWIMR, 0x20);
+					// 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation.
+					rtw_write8(padapter, REG_FTIMR, 0x00);
+					rtw_write8(padapter, REG_FSIMR, 0x00);
+
+					rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
+
+					while( (retry_cnts++ <100) && (FEN_CPUEN &rtw_read16(padapter, REG_SYS_FUNC_EN)))
+					{
+						rtw_udelay_os(50);//us
+						// 2010/08/25 For test only We keep on reset 5051 to prevent fail.
+						//rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
+					}
+//					RT_ASSERT((retry_cnts < 100), ("8051 reset failed!\n"));
+
+					if (retry_cnts >= 100)
+					{
+						// if 8051 reset fail we trigger GPIO 0 for LA
+						//rtw_write32(	padapter,
+						//						REG_GPIO_PIN_CTRL,
+						//						0x00010100);
+						// 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly.
+						rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x50);	//Reset MAC and Enable 8051
+						rtw_mdelay_os(10);
+					}
+//					else
+//					RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 reset success (%d) .\n",retry_cnts));
+				}
+			}
+//			else
+//			{
+//				RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 in ROM.\n"));
+//			}
+			rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54);	//Reset MAC and Enable 8051
+			rtw_write8(padapter, REG_MCUFWDL, 0);
+		}
+	}
+
+	//if(pDevice->RegUsbSS)
+		//bWithoutHWSM = TRUE;	// Sugest by Filen and Issau.
+
+	if(bWithoutHWSM)
+	{
+		//HAL_DATA_TYPE		*pHalData	= GET_HAL_DATA(padapter);
+	/*****************************
+		Without HW auto state machine
+	g.	SYS_CLKR 0x08[15:0] = 0x30A3			//disable MAC clock
+	h.	AFE_PLL_CTRL 0x28[7:0] = 0x80			//disable AFE PLL
+	i.	AFE_XTAL_CTRL 0x24[15:0] = 0x880F		//gated AFE DIG_CLOCK
+	j.	SYS_ISO_CTRL 0x00[7:0] = 0xF9			// isolated digital to PON
+	******************************/
+		//rtw_write16(padapter, REG_SYS_CLKR, 0x30A3);
+		//if(!pDevice->RegUsbSS)
+		// 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
+			rtw_write16(padapter, REG_SYS_CLKR, 0x70A3);  //modify to 0x70A3 by Scott.
+		rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
+		rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
+		//if(!pDevice->RegUsbSS)
+			rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
+	}
+	else
+	{
+		// Disable all RF/BB power
+		rtw_write8(padapter, REG_RF_CTRL, 0x00);
+	}
+//	RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Reset Digital.\n"));
+
+}
+
+void _ResetDigitalProcedure1(PADAPTER padapter, BOOLEAN bWithoutHWSM)
+{
+	_ResetDigitalProcedure1_8703B(padapter, bWithoutHWSM);
+}
+
+void _ResetDigitalProcedure2(PADAPTER padapter)
+{
+	//HAL_DATA_TYPE		*pHalData	= GET_HAL_DATA(padapter);
+/*****************************
+k.	SYS_FUNC_EN 0x03[7:0] = 0x44			// disable ELDR runction
+l.	SYS_CLKR 0x08[15:0] = 0x3083			// disable ELDR clock
+m.	SYS_ISO_CTRL 0x01[7:0] = 0x83			// isolated ELDR to PON
+******************************/
+	//rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x44); //marked by Scott.
+	// 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
+		rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); //modify to 0x70a3 by Scott.
+	rtw_write8(padapter, REG_SYS_ISO_CTRL+1, 0x82); //modify to 0x82 by Scott.
+}
+
+void _DisableAnalog(PADAPTER padapter, BOOLEAN bWithoutHWSM)
+{
+	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
+	u16 value16 = 0;
+	u8 value8 = 0;
+
+
+	if (bWithoutHWSM)
+	{
+		/*****************************
+		n.	LDOA15_CTRL 0x20[7:0] = 0x04		// disable A15 power
+		o.	LDOV12D_CTRL 0x21[7:0] = 0x54		// disable digital core power
+		r.	When driver call disable, the ASIC will turn off remaining clock automatically
+		******************************/
+
+		rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
+		//rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54);
+
+		value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
+		value8 &= (~LDV12_EN);
+		rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
+//		RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8));
+	}
+
+	/*****************************
+	h.	SPS0_CTRL 0x11[7:0] = 0x23			//enter PFM mode
+	i.	APS_FSMCO 0x04[15:0] = 0x4802		// set USB suspend
+	******************************/
+	value8 = 0x23;
+
+	rtw_write8(padapter, REG_SPS0_CTRL, value8);
+
+	if(bWithoutHWSM)
+	{
+		//value16 |= (APDM_HOST | /*AFSM_HSUS |*/PFM_ALDN);
+		// 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically.
+		// Becasue suspend operatione need the asistance of 8051 to wait for 3ms.
+		value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
+	}
+	else
+	{
+		value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
+	}
+
+	rtw_write16(padapter, REG_APS_FSMCO, value16);//0x4802
+
+	rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
+
+#if 0
+	//tynli_test for suspend mode.
+	if(!bWithoutHWSM){
+		rtw_write8(padapter, 0xfe10, 0x19);
+	}
+#endif
+
+//	RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable Analog Reg0x04:0x%04x.\n",value16));
+}
+
+// HW Auto state machine
+s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU)
+{
+	int rtStatus = _SUCCESS;
+
+
+	if (RTW_CANNOT_RUN(padapter))
+		return rtStatus;
+
+	//==== RF Off Sequence ====
+	_DisableRFAFEAndResetBB(padapter);
+
+	//  ==== Reset digital sequence   ======
+	_ResetDigitalProcedure1(padapter, _FALSE);
+
+	//  ==== Pull GPIO PIN to balance level and LED control ======
+	_DisableGPIO(padapter);
+
+	//  ==== Disable analog sequence ===
+	_DisableAnalog(padapter, _FALSE);
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n"));
+
+	return rtStatus;
+}
+
+// without HW Auto state machine
+s32 CardDisableWithoutHWSM(PADAPTER padapter)
+{
+	s32 rtStatus = _SUCCESS;
+
+
+	//RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Card Disable Without HWSM .\n"));
+	if (RTW_CANNOT_RUN(padapter))
+		return rtStatus;
+
+
+	//==== RF Off Sequence ====
+	_DisableRFAFEAndResetBB(padapter);
+
+	//  ==== Reset digital sequence   ======
+	_ResetDigitalProcedure1(padapter, _TRUE);
+
+	//  ==== Pull GPIO PIN to balance level and LED control ======
+	_DisableGPIO(padapter);
+
+	//  ==== Reset digital sequence   ======
+	_ResetDigitalProcedure2(padapter);
+
+	//  ==== Disable analog sequence ===
+	_DisableAnalog(padapter, _TRUE);
+
+	//RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n"));
+	return rtStatus;
+}
+#endif // CONFIG_USB_HCI || CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
+
+BOOLEAN 
+Hal_GetChnlGroup8703B(
+	IN	u8 Channel,
+	OUT u8 *pGroup
+	)
+{
+	BOOLEAN bIn24G=TRUE;
+
+	if(Channel <= 14)
+	{
+		bIn24G=TRUE;
+
+		if      (1  <= Channel && Channel <= 2 )   *pGroup = 0;
+		else if (3  <= Channel && Channel <= 5 )   *pGroup = 1;
+		else if (6  <= Channel && Channel <= 8 )   *pGroup = 2;
+		else if (9  <= Channel && Channel <= 11)   *pGroup = 3;
+		else if (12 <= Channel && Channel <= 14)   *pGroup = 4;
+		else
+		{
+			RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,("==>Hal_GetChnlGroup8703B in 2.4 G, but Channel %d in Group not found \n", Channel));
+		}
+	}
+	else
+	{
+		bIn24G=FALSE;
+
+		if      (36   <= Channel && Channel <=  42)   *pGroup = 0;
+		else if (44   <= Channel && Channel <=  48)   *pGroup = 1;
+		else if (50   <= Channel && Channel <=  58)   *pGroup = 2;
+		else if (60   <= Channel && Channel <=  64)   *pGroup = 3;
+		else if (100  <= Channel && Channel <= 106)   *pGroup = 4;
+		else if (108  <= Channel && Channel <= 114)   *pGroup = 5;
+		else if (116  <= Channel && Channel <= 122)   *pGroup = 6;
+		else if (124  <= Channel && Channel <= 130)   *pGroup = 7;
+		else if (132  <= Channel && Channel <= 138)   *pGroup = 8;
+		else if (140  <= Channel && Channel <= 144)   *pGroup = 9;
+		else if (149  <= Channel && Channel <= 155)   *pGroup = 10;
+		else if (157  <= Channel && Channel <= 161)   *pGroup = 11;
+		else if (165  <= Channel && Channel <= 171)   *pGroup = 12;
+		else if (173  <= Channel && Channel <= 177)   *pGroup = 13;
+		else
+		{
+			RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,("==>Hal_GetChnlGroup8703B in 5G, but Channel %d in Group not found \n",Channel));
+		}
+
+	}
+	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("<==Hal_GetChnlGroup8703B,  (%s) Channel = %d, Group =%d,\n", 
+                                  (bIn24G) ? "2.4G" : "5G", Channel, *pGroup));
+	return bIn24G;
+}
+
+void
+Hal_InitPGData(
+	PADAPTER	padapter,
+	u8			*PROMContent)
+{
+
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u32			i;
+	u16			value16;
+
+	if(_FALSE == pHalData->bautoload_fail_flag)
+	{ // autoload OK.
+//		if (IS_BOOT_FROM_EEPROM(padapter))
+		if (_TRUE == pHalData->EepromOrEfuse)
+		{
+			// Read all Content from EEPROM or EFUSE.
+			for(i = 0; i < HWSET_MAX_SIZE_8703B; i += 2)
+			{
+//				value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1)));
+//				*((u16*)(&PROMContent[i])) = value16;
+			}
+		}
+		else
+		{
+			// Read EFUSE real map to shadow.
+			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
+			_rtw_memcpy((void*)PROMContent, (void*)pHalData->efuse_eeprom_data, HWSET_MAX_SIZE_8703B);
+		}
+	}
+	else
+	{//autoload fail
+		RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
+//		pHalData->AutoloadFailFlag = _TRUE;
+		//update to default value 0xFF
+		if (_FALSE == pHalData->EepromOrEfuse)
+			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
+		_rtw_memcpy((void*)PROMContent, (void*)pHalData->efuse_eeprom_data, HWSET_MAX_SIZE_8703B);
+	}
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+	if (check_phy_efuse_tx_power_info_valid(padapter) == _FALSE) {
+		if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS)
+			DBG_871X_LEVEL(_drv_err_, "invalid phy efuse and read from file fail, will use driver default!!\n");
+	}
+#endif
+}
+
+void
+Hal_EfuseParseIDCode(
+	IN	PADAPTER	padapter,
+	IN	u8			*hwinfo
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	u16			EEPROMId;
+
+
+	// Checl 0x8129 again for making sure autoload status!!
+	EEPROMId = le16_to_cpu(*((u16*)hwinfo));
+	if (EEPROMId != RTL_EEPROM_ID)
+	{
+		DBG_8192C("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
+		pHalData->bautoload_fail_flag = _TRUE;
+	}
+	else
+	{
+		pHalData->bautoload_fail_flag = _FALSE;
+	}
+
+	RT_TRACE(_module_hal_init_c_, _drv_notice_, ("EEPROM ID=0x%04x\n", EEPROMId));
+}
+
+static void
+Hal_EEValueCheck(
+	IN		u8		EEType,
+	IN		PVOID		pInValue,
+	OUT		PVOID		pOutValue
+	)
+{
+	switch(EEType)
+	{
+		case EETYPE_TX_PWR:
+			{
+				u8	*pIn, *pOut;
+				pIn = (u8*)pInValue;
+				pOut = (u8*)pOutValue;
+				if(*pIn <= 63)
+				{
+					*pOut = *pIn;
+				}
+				else
+				{
+					RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("EETYPE_TX_PWR, value=%d is invalid, set to default=0x%x\n",
+						*pIn, EEPROM_Default_TxPowerLevel));
+					*pOut = EEPROM_Default_TxPowerLevel;
+				}
+			}
+			break;
+		default:
+			break;
+	}
+}
+
+static u8
+Hal_GetChnlGroup(
+	IN	u8 chnl
+	)
+{
+	u8	group=0;
+
+	if (chnl < 3)			// Cjanel 1-3
+		group = 0;
+	else if (chnl < 9)		// Channel 4-9
+		group = 1;
+	else					// Channel 10-14
+		group = 2;
+
+	return group;
+}
+
+void 
+Hal_ReadPowerValueFromPROM_8703B(
+	IN	PADAPTER 		Adapter,
+	IN	PTxPowerInfo24G	pwrInfo24G,
+	IN	u8 				* PROMContent,
+	IN	BOOLEAN			AutoLoadFail
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	u4Byte rfPath, eeAddr=EEPROM_TX_PWR_INX_8703B, group,TxCount=0;
+
+	_rtw_memset(pwrInfo24G, 0, sizeof(TxPowerInfo24G));	
+
+	if(0xFF == PROMContent[eeAddr+1])  
+		AutoLoadFail = TRUE;
+	
+	if(AutoLoadFail)
+	{	
+		DBG_871X("%s(): Use Default value!\n", __func__);
+		for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
+		{
+			//2.4G default value
+			for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
+			{
+				pwrInfo24G->IndexCCK_Base[rfPath][group] =	EEPROM_DEFAULT_24G_INDEX;
+				pwrInfo24G->IndexBW40_Base[rfPath][group] =	EEPROM_DEFAULT_24G_INDEX;
+			}
+			for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
+			{
+				if(TxCount==0)
+				{
+					pwrInfo24G->BW20_Diff[rfPath][0] =	EEPROM_DEFAULT_24G_HT20_DIFF;
+					pwrInfo24G->OFDM_Diff[rfPath][0] =	EEPROM_DEFAULT_24G_OFDM_DIFF;
+				}
+				else
+				{
+					pwrInfo24G->BW20_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_DIFF;
+					pwrInfo24G->BW40_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_DIFF;
+					pwrInfo24G->CCK_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_DIFF;
+					pwrInfo24G->OFDM_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_DIFF;
+				}
+			}
+		}
+		
+		return;
+	}	
+
+	pHalData->bTXPowerDataReadFromEEPORM = TRUE;		//YJ,move,120316
+	
+	for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
+	{
+		//2 2.4G default value
+		for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
+		{
+			pwrInfo24G->IndexCCK_Base[rfPath][group] =	PROMContent[eeAddr++];
+			if(pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
+			{
+				pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
+			}
+		}
+		for(group = 0 ; group < MAX_CHNL_GROUP_24G-1; group++)
+		{
+			pwrInfo24G->IndexBW40_Base[rfPath][group] =	PROMContent[eeAddr++];
+			if(pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
+				pwrInfo24G->IndexBW40_Base[rfPath][group] =	EEPROM_DEFAULT_24G_INDEX;
+		}			
+		for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
+		{
+			if(TxCount==0)
+			{
+				pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
+				pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
+				if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)		/*4bit sign number to 8 bit sign number*/
+					pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
+
+				pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
+				if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)		/*4bit sign number to 8 bit sign number*/
+					pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
+
+				pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
+				eeAddr++;
+			} else{
+				pwrInfo24G->BW40_Diff[rfPath][TxCount] =	(PROMContent[eeAddr]&0xf0)>>4;
+				if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3)		/*4bit sign number to 8 bit sign number*/
+					pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
+
+				pwrInfo24G->BW20_Diff[rfPath][TxCount] =	(PROMContent[eeAddr]&0x0f);
+				if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)		/*4bit sign number to 8 bit sign number*/
+					pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
+
+				eeAddr++;
+
+				pwrInfo24G->OFDM_Diff[rfPath][TxCount] =	(PROMContent[eeAddr]&0xf0)>>4;
+				if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)		/*4bit sign number to 8 bit sign number*/
+					pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
+
+
+				pwrInfo24G->CCK_Diff[rfPath][TxCount] =	(PROMContent[eeAddr]&0x0f);
+				if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3)		/*4bit sign number to 8 bit sign number*/
+					pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
+
+				eeAddr++;
+			}
+		}
+
+		/* Ignore the unnecessary 5G parameters parsing, but still consider the efuse address offset */
+		#define	TX_PWR_DIFF_OFFSET_5G	10
+		eeAddr += (MAX_CHNL_GROUP_5G + TX_PWR_DIFF_OFFSET_5G);
+	}
+}
+
+
+void
+Hal_EfuseParseTxPowerInfo_8703B(
+	IN	PADAPTER 		padapter,
+	IN	u8*			PROMContent,
+	IN	BOOLEAN			AutoLoadFail
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	TxPowerInfo24G	pwrInfo24G;
+	u8			rfPath, ch, group, TxCount=1;
+
+//	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
+	Hal_ReadPowerValueFromPROM_8703B(padapter, &pwrInfo24G, PROMContent, AutoLoadFail);
+	for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
+	{
+		for (ch = 0 ; ch < CENTER_CH_2G_NUM; ch++) {
+			Hal_GetChnlGroup8703B(ch+1, &group);
+			
+			if(ch == 14-1) 
+			{
+				pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][5];
+				pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
+			}
+			else
+			{
+				pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
+				pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
+			}
+#ifdef CONFIG_DEBUG
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======= Path %d, ChannelIndex %d, Group %d=======\n",rfPath,ch, group));			
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_CCK_Base[%d][%d] = 0x%x\n",rfPath,ch ,pHalData->Index24G_CCK_Base[rfPath][ch]));
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_BW40_Base[%d][%d] = 0x%x\n",rfPath,ch,pHalData->Index24G_BW40_Base[rfPath][ch]));			
+#endif							
+		}
+		
+		for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
+		{
+			pHalData->CCK_24G_Diff[rfPath][TxCount]=pwrInfo24G.CCK_Diff[rfPath][TxCount];
+			pHalData->OFDM_24G_Diff[rfPath][TxCount]=pwrInfo24G.OFDM_Diff[rfPath][TxCount];
+			pHalData->BW20_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW20_Diff[rfPath][TxCount];
+			pHalData->BW40_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW40_Diff[rfPath][TxCount];
+			
+#ifdef CONFIG_DEBUG
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("--------------------------------------- 2.4G ---------------------------------------\n"));
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("CCK_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->CCK_24G_Diff[rfPath][TxCount]));
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("OFDM_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->OFDM_24G_Diff[rfPath][TxCount]));
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW20_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW20_24G_Diff[rfPath][TxCount]));
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW40_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW40_24G_Diff[rfPath][TxCount]));
+#endif							
+		}
+	}
+
+	// 2010/10/19 MH Add Regulator recognize for CU.
+	if(!AutoLoadFail)
+	{
+		pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8703B]&0x7);	//bit0~2
+		if(PROMContent[EEPROM_RF_BOARD_OPTION_8703B] == 0xFF)
+			pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7);	//bit0~2
+	}
+	else
+	{
+		pHalData->EEPROMRegulatory = 0;
+	}
+	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
+}
+
+VOID
+Hal_EfuseParseBoardType_8703B(
+	IN	PADAPTER	Adapter,	
+	IN	u8*			PROMContent,
+	IN	BOOLEAN		AutoloadFail
+	)
+{
+
+
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+
+	if(!AutoloadFail)
+	{
+		pHalData->InterfaceSel = (PROMContent[EEPROM_RF_BOARD_OPTION_8703B]&0xE0)>>5;
+		if(PROMContent[EEPROM_RF_BOARD_OPTION_8703B] == 0xFF)
+			pHalData->InterfaceSel = (EEPROM_DEFAULT_BOARD_OPTION&0xE0)>>5;
+	}
+	else
+	{
+		pHalData->InterfaceSel = 0;
+	}
+	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("Board Type: 0x%2x\n", pHalData->InterfaceSel));
+
+}
+
+VOID
+Hal_EfuseParseBTCoexistInfo_8703B(
+	IN PADAPTER			padapter,
+	IN u8*			hwinfo,
+	IN BOOLEAN			AutoLoadFail
+	)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	u8			tempval;
+	u32			tmpu4;
+
+//	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
+	if (!AutoLoadFail)
+	{
+		tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
+		if (tmpu4 & BT_FUNC_EN)
+			pHalData->EEPROMBluetoothCoexist = _TRUE;
+		else
+			pHalData->EEPROMBluetoothCoexist = _FALSE;
+
+		pHalData->EEPROMBluetoothType = BT_RTL8703B;
+
+		tempval = hwinfo[EEPROM_RF_BT_SETTING_8703B];
+		if(tempval !=0xFF){
+			pHalData->EEPROMBluetoothAntNum = tempval & BIT(0);
+			#ifdef CONFIG_USB_HCI
+			/*if(rtw_get_intf_type(padapter) == RTW_USB)*/
+			pHalData->ant_path =ODM_RF_PATH_B;//s0
+			#else //SDIO or PCIE
+			// EFUSE_0xC3[6] == 0, S1(Main)-ODM_RF_PATH_A;
+			// EFUSE_0xC3[6] == 1, S0(Aux)-ODM_RF_PATH_B
+			pHalData->ant_path = (tempval & BIT(6))?ODM_RF_PATH_B:ODM_RF_PATH_A;
+			#endif
+		}
+		else{
+			pHalData->EEPROMBluetoothAntNum = Ant_x1;
+			#ifdef CONFIG_USB_HCI
+			pHalData->ant_path = ODM_RF_PATH_B;//s0
+			#else
+			pHalData->ant_path = ODM_RF_PATH_A;
+			#endif			
+		}
+	}
+	else
+	{
+		if (padapter->registrypriv.mp_mode == 1)
+			pHalData->EEPROMBluetoothCoexist = _TRUE;
+		else
+			pHalData->EEPROMBluetoothCoexist = _FALSE;
+		pHalData->EEPROMBluetoothType = BT_RTL8703B;
+		pHalData->EEPROMBluetoothAntNum = Ant_x1;
+		#ifdef CONFIG_USB_HCI
+		pHalData->ant_path = ODM_RF_PATH_B;//s0
+		#else
+		pHalData->ant_path = ODM_RF_PATH_A;
+		#endif
+	}
+
+#ifdef CONFIG_BT_COEXIST
+	if (padapter->registrypriv.ant_num > 0) {
+		DBG_8192C("%s: Apply driver defined antenna number(%d) to replace origin(%d)\n",
+			__FUNCTION__,
+			padapter->registrypriv.ant_num,
+			pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
+
+		switch (padapter->registrypriv.ant_num) {
+		case 1:
+			pHalData->EEPROMBluetoothAntNum = Ant_x1;
+			break;
+		case 2:
+			pHalData->EEPROMBluetoothAntNum = Ant_x2;
+			break;
+		default:
+			DBG_8192C("%s: Discard invalid driver defined antenna number(%d)!\n",
+				__FUNCTION__, padapter->registrypriv.ant_num);
+			break;
+		}
+	}
+
+	rtw_btcoex_SetBTCoexist(padapter, pHalData->EEPROMBluetoothCoexist);
+	rtw_btcoex_SetChipType(padapter, pHalData->EEPROMBluetoothType);
+	rtw_btcoex_SetPGAntNum(padapter, pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1); 
+	if (pHalData->EEPROMBluetoothAntNum == Ant_x1)
+	{
+		rtw_btcoex_SetSingleAntPath(padapter, pHalData->ant_path);
+	}
+#endif // CONFIG_BT_COEXIST
+
+	DBG_8192C("%s: %s BT-coex, ant_num=%d\n",
+		__FUNCTION__,
+		pHalData->EEPROMBluetoothCoexist==_TRUE?"Enable":"Disable",
+		pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
+}
+
+VOID
+Hal_EfuseParseEEPROMVer_8703B(
+	IN	PADAPTER		padapter,
+	IN	u8*			hwinfo,
+	IN	BOOLEAN			AutoLoadFail
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+//	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
+	if(!AutoLoadFail)
+		pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8703B];
+	else
+		pHalData->EEPROMVersion = 1;
+	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
+		pHalData->EEPROMVersion));
+}
+
+VOID
+Hal_EfuseParseVoltage_8703B(
+	IN	PADAPTER		pAdapter,
+	IN	u8* 			hwinfo,
+	IN	BOOLEAN 	AutoLoadFail
+	) 
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+
+	//_rtw_memcpy(pHalData->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8703B], 1);
+	DBG_871X("%s hwinfo[EEPROM_Voltage_ADDR_8703B] =%02x \n",__func__, hwinfo[EEPROM_Voltage_ADDR_8703B]);
+	pHalData->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8703B] & 0xf0) >> 4 ;
+	DBG_871X("%s pHalData->adjuseVoltageVal =%x \n",__func__,pHalData->adjuseVoltageVal);
+}
+
+VOID
+Hal_EfuseParseChnlPlan_8703B(
+	IN	PADAPTER		padapter,
+	IN	u8*			hwinfo,
+	IN	BOOLEAN			AutoLoadFail
+	)
+{
+	padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
+		padapter
+		, hwinfo?hwinfo[EEPROM_ChannelPlan_8703B]:0xFF
+		, padapter->registrypriv.channel_plan
+		, RTW_CHPLAN_WORLD_NULL
+		, AutoLoadFail
+	);
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM ChannelPlan=0x%02x\n", padapter->mlmepriv.ChannelPlan));
+}
+
+VOID
+Hal_EfuseParseCustomerID_8703B(
+	IN	PADAPTER		padapter,
+	IN	u8*			hwinfo,
+	IN	BOOLEAN			AutoLoadFail
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+//	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
+	if (!AutoLoadFail)
+	{
+		pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8703B];
+	}
+	else
+	{
+		pHalData->EEPROMCustomerID = 0;
+	}
+	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
+}
+
+VOID
+Hal_EfuseParseAntennaDiversity_8703B(
+	IN	PADAPTER		pAdapter,
+	IN	u8				* hwinfo,
+	IN	BOOLEAN			AutoLoadFail
+	)
+{
+#ifdef CONFIG_ANTENNA_DIVERSITY
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(pAdapter);
+	struct registry_priv	*registry_par = &pAdapter->registrypriv;
+
+	if (pHalData->EEPROMBluetoothAntNum == Ant_x1){
+		pHalData->AntDivCfg = 0;
+	}
+	else{
+		if(registry_par->antdiv_cfg == 2)// 0:OFF , 1:ON, 2:By EFUSE
+			pHalData->AntDivCfg = 1;
+		else
+			pHalData->AntDivCfg = registry_par->antdiv_cfg;
+	}
+
+	// If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead.
+	if(registry_par->antdiv_type == 0) {
+		pHalData->TRxAntDivType = hwinfo[EEPROM_RFE_OPTION_8703B];
+		if (pHalData->TRxAntDivType == 0xFF)
+			pHalData->TRxAntDivType = S0S1_SW_ANTDIV;//GetRegAntDivType(pAdapter);
+		else if (pHalData->TRxAntDivType == 0x10)
+			pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1
+		else if (pHalData->TRxAntDivType == 0x11)
+			pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1
+		else
+			DBG_8192C("%s: efuse[0x%x]=0x%02x is unknown type\n",
+				__FUNCTION__, EEPROM_RFE_OPTION_8703B, pHalData->TRxAntDivType);
+	}
+	else{
+		pHalData->TRxAntDivType = registry_par->antdiv_type ;//GetRegAntDivType(pAdapter);
+	}
+
+	DBG_8192C("%s: AntDivCfg=%d, AntDivType=%d\n",
+		__FUNCTION__, pHalData->AntDivCfg, pHalData->TRxAntDivType);
+#endif
+}
+
+VOID
+Hal_EfuseParseXtal_8703B(
+	IN	PADAPTER		pAdapter,
+	IN	u8			* hwinfo,
+	IN	BOOLEAN		AutoLoadFail
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+
+//	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
+	if(!AutoLoadFail)
+	{
+		pHalData->CrystalCap = hwinfo[EEPROM_XTAL_8703B];
+		if(pHalData->CrystalCap == 0xFF)
+			pHalData->CrystalCap = EEPROM_Default_CrystalCap_8703B;	   //what value should 8812 set?
+	}
+	else
+	{
+		pHalData->CrystalCap = EEPROM_Default_CrystalCap_8703B;
+	}
+	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM CrystalCap: 0x%2x\n", pHalData->CrystalCap));
+}
+
+
+void
+Hal_EfuseParseThermalMeter_8703B(
+	PADAPTER	padapter,
+	u8			*PROMContent,
+	u8			AutoLoadFail
+	)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+
+//	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
+	//
+	// ThermalMeter from EEPROM
+	//
+	if (_FALSE == AutoLoadFail)
+		pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8703B];
+	else
+		pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8703B;
+
+	if ((pHalData->EEPROMThermalMeter == 0xff) || (_TRUE == AutoLoadFail))
+	{
+		pHalData->odmpriv.RFCalibrateInfo.bAPKThermalMeterIgnore = _TRUE;
+		pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8703B;
+	}
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM ThermalMeter=0x%x\n", pHalData->EEPROMThermalMeter));
+}
+
+
+void Hal_ReadRFGainOffset(
+	IN		PADAPTER		Adapter,
+	IN		u8* 			PROMContent,
+	IN		BOOLEAN 		AutoloadFail)
+{
+#ifdef CONFIG_RF_GAIN_OFFSET
+
+		HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+		struct kfree_data_t *kfree_data = &pHalData->kfree_data;
+
+		DBG_871X("%s, kfree config:%d\n", __func__, Adapter->registrypriv.RegRfKFreeEnable);
+
+		if ((Adapter->registrypriv.RegRfKFreeEnable == 1) || !AutoloadFail) {
+			kfree_data->bb_gain[BB_GAIN_2G][RF_PATH_A]
+				= KFREE_BB_GAIN_2G_TX_OFFSET(EFUSE_Read1Byte(Adapter, PPG_BB_GAIN_2G_TXA_OFFSET_8703B) & PPG_BB_GAIN_2G_TX_OFFSET_MASK);
+			kfree_data->thermal
+				= KFREE_THERMAL_OFFSET(EFUSE_Read1Byte(Adapter, PPG_THERMAL_OFFSET_8703B) & PPG_THERMAL_OFFSET_MASK);
+
+			if (GET_PG_KFREE_ON_8703B(PROMContent) && PROMContent[0xc1] != 0xff)
+				kfree_data->flag |= KFREE_FLAG_ON;
+			if (GET_PG_KFREE_THERMAL_K_ON_8703B(PROMContent) && PROMContent[0xc8] != 0xff)
+				kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON;
+		}
+
+		if (Adapter->registrypriv.RegRfKFreeEnable == 1) {
+				kfree_data->flag |= KFREE_FLAG_ON;
+				kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON;
+		}
+
+		if (kfree_data->flag & KFREE_FLAG_THERMAL_K_ON)
+			pHalData->EEPROMThermalMeter += kfree_data->thermal;
+
+		DBG_871X("kfree flag:%u\n", kfree_data->flag);
+		if (Adapter->registrypriv.RegRfKFreeEnable == 1 || kfree_data->flag & KFREE_FLAG_ON)
+			DBG_871X("bb_gain:%d\n", kfree_data->bb_gain[BB_GAIN_2G][RF_PATH_A]);
+		if (Adapter->registrypriv.RegRfKFreeEnable == 1 || kfree_data->flag & KFREE_FLAG_THERMAL_K_ON)
+			DBG_871X("thermal:%d\n", kfree_data->thermal);
+
+#endif /*CONFIG_RF_GAIN_OFFSET */
+
+}
+
+
+u8 
+BWMapping_8703B(
+	IN	PADAPTER		Adapter,
+	IN	struct pkt_attrib	*pattrib
+)
+{
+	u8	BWSettingOfDesc = 0;
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+
+	//DBG_871X("BWMapping pHalData->CurrentChannelBW %d, pattrib->bwmode %d \n",pHalData->CurrentChannelBW,pattrib->bwmode);
+
+	if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_80)
+	{
+		if(pattrib->bwmode == CHANNEL_WIDTH_80)
+			BWSettingOfDesc= 2;
+		else if(pattrib->bwmode == CHANNEL_WIDTH_40)
+			BWSettingOfDesc = 1;
+		else
+			BWSettingOfDesc = 0;
+	}
+	else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
+	{
+		if((pattrib->bwmode == CHANNEL_WIDTH_40) || (pattrib->bwmode == CHANNEL_WIDTH_80))
+			BWSettingOfDesc = 1;
+		else
+			BWSettingOfDesc = 0;
+	}
+	else
+		BWSettingOfDesc = 0;
+
+	//if(pTcb->bBTTxPacket)
+	//	BWSettingOfDesc = 0;
+
+	return BWSettingOfDesc;
+}
+
+u8	SCMapping_8703B(PADAPTER Adapter, struct pkt_attrib *pattrib)
+{
+	u8	SCSettingOfDesc = 0;
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+
+	//DBG_871X("SCMapping: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC);
+	
+	if(pHalData->CurrentChannelBW == CHANNEL_WIDTH_80)
+	{
+		if(pattrib->bwmode == CHANNEL_WIDTH_80)
+		{
+			SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
+		}
+		else if(pattrib->bwmode == CHANNEL_WIDTH_40)
+		{
+			if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
+				SCSettingOfDesc = VHT_DATA_SC_40_LOWER_OF_80MHZ;
+			else if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
+				SCSettingOfDesc = VHT_DATA_SC_40_UPPER_OF_80MHZ;
+			else
+				DBG_871X("SCMapping: DONOT CARE Mode Setting\n");
+		}
+		else
+		{
+			if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
+				SCSettingOfDesc = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
+			else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
+				SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
+			else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
+				SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
+			else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
+				SCSettingOfDesc = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
+			else
+				DBG_871X("SCMapping: DONOT CARE Mode Setting\n");
+		}
+	}
+	else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
+	{
+		//DBG_871X("SCMapping: HT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur40MhzPrimeSC);
+
+		if(pattrib->bwmode == CHANNEL_WIDTH_40)
+		{
+			SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
+		}
+		else if(pattrib->bwmode == CHANNEL_WIDTH_20)
+		{
+			if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
+			{
+				SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
+			}
+			else if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
+			{
+				SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
+			}
+			else
+			{
+				SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
+			}
+		}
+	}
+	else
+	{
+		SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
+	}
+
+	return SCSettingOfDesc;
+}
+
+
+static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib)
+{
+	u8 sectype = 0;
+	if ((pattrib->encrypt > 0) && !pattrib->bswenc)
+	{
+		switch (pattrib->encrypt)
+		{
+			// SEC_TYPE
+			case _WEP40_:
+			case _WEP104_:
+			case _TKIP_:
+			case _TKIP_WTMIC_:
+				sectype = 1;
+				break;
+
+#ifdef CONFIG_WAPI_SUPPORT
+			case _SMS4_:
+				sectype = 2;
+				break;
+#endif
+			case _AES_:
+				sectype = 3;
+				break;
+
+			case _NO_PRIVACY_:
+			default:
+					break;
+		}
+	}
+	return sectype;
+}
+
+static void fill_txdesc_vcs_8703b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
+{
+	//DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
+
+	if (pattrib->vcs_mode) {
+		switch (pattrib->vcs_mode) {
+		case RTS_CTS:
+			SET_TX_DESC_RTS_ENABLE_8703B(ptxdesc, 1);
+			SET_TX_DESC_HW_RTS_ENABLE_8703B(ptxdesc, 1);
+			break;
+
+		case CTS_TO_SELF:
+			SET_TX_DESC_CTS2SELF_8703B(ptxdesc, 1);
+			break;
+
+		case NONE_VCS:
+		default:
+			break;
+		}
+
+		SET_TX_DESC_RTS_RATE_8703B(ptxdesc, 8); // RTS Rate=24M
+		SET_TX_DESC_RTS_RATE_FB_LIMIT_8703B(ptxdesc, 0xF);
+
+		if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT) {
+			SET_TX_DESC_RTS_SHORT_8703B(ptxdesc, 1);
+		}
+
+		// Set RTS BW
+		if (pattrib->ht_en) {
+			SET_TX_DESC_RTS_SC_8703B(ptxdesc, SCMapping_8703B(padapter, pattrib));
+		}
+	}
+}
+
+static void fill_txdesc_phy_8703b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
+{
+	//DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
+
+	if (pattrib->ht_en) {
+		SET_TX_DESC_DATA_BW_8703B(ptxdesc, BWMapping_8703B(padapter, pattrib));
+		SET_TX_DESC_DATA_SC_8703B(ptxdesc, SCMapping_8703B(padapter, pattrib));
+	}
+}
+
+static void rtl8703b_fill_default_txdesc(
+	struct xmit_frame *pxmitframe,
+	u8 *pbuf)
+{
+	PADAPTER padapter;
+	HAL_DATA_TYPE *pHalData;
+	struct mlme_ext_priv *pmlmeext;
+	struct mlme_ext_info *pmlmeinfo;
+	struct pkt_attrib *pattrib;
+	s32 bmcst;
+
+	_rtw_memset(pbuf, 0, TXDESC_SIZE);
+
+	padapter = pxmitframe->padapter;
+	pHalData = GET_HAL_DATA(padapter);
+	pmlmeext = &padapter->mlmeextpriv;
+	pmlmeinfo = &(pmlmeext->mlmext_info);
+
+	pattrib = &pxmitframe->attrib;
+	bmcst = IS_MCAST(pattrib->ra);
+
+	if (pxmitframe->frame_tag == DATA_FRAMETAG)
+	{
+		u8 drv_userate = 0;
+
+		SET_TX_DESC_MACID_8703B(pbuf, pattrib->mac_id);
+		SET_TX_DESC_RATE_ID_8703B(pbuf, pattrib->raid);
+		SET_TX_DESC_QUEUE_SEL_8703B(pbuf, pattrib->qsel);
+		SET_TX_DESC_SEQ_8703B(pbuf, pattrib->seqnum);
+
+		SET_TX_DESC_SEC_TYPE_8703B(pbuf, fill_txdesc_sectype(pattrib));
+		fill_txdesc_vcs_8703b(padapter, pattrib, pbuf);
+
+#ifdef CONFIG_P2P
+		if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
+			if (pattrib->icmp_pkt == 1 && padapter->registrypriv.wifi_spec == 1)
+				drv_userate = 1;
+		}
+#endif
+
+		if ((pattrib->ether_type != 0x888e) &&
+			(pattrib->ether_type != 0x0806) &&
+			(pattrib->ether_type != 0x88B4) &&
+			(pattrib->dhcp_pkt != 1) &&
+			(drv_userate != 1)
+#ifdef CONFIG_AUTO_AP_MODE
+		    && (pattrib->pctrl != _TRUE)
+#endif
+			)
+		{
+			// Non EAP & ARP & DHCP type data packet
+
+			if (pattrib->ampdu_en == _TRUE) {
+				SET_TX_DESC_AGG_ENABLE_8703B(pbuf, 1);
+				SET_TX_DESC_MAX_AGG_NUM_8703B(pbuf, 0x1F);
+				SET_TX_DESC_AMPDU_DENSITY_8703B(pbuf, pattrib->ampdu_spacing);
+			}
+			else {
+				SET_TX_DESC_AGG_BREAK_8703B(pbuf, 1);
+			}
+
+			fill_txdesc_phy_8703b(padapter, pattrib, pbuf);
+
+			SET_TX_DESC_DATA_RATE_FB_LIMIT_8703B(pbuf, 0x1F);
+
+			if (pHalData->fw_ractrl == _FALSE) {
+				SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
+
+				if (pHalData->INIDATA_RATE[pattrib->mac_id] & BIT(7)) {
+					SET_TX_DESC_DATA_SHORT_8703B(pbuf, 1);
+				}
+
+				SET_TX_DESC_TX_RATE_8703B(pbuf, pHalData->INIDATA_RATE[pattrib->mac_id] & 0x7F);
+			}
+
+			// modify data rate by iwpriv
+			if (padapter->fix_rate != 0xFF) {
+				SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
+				if (padapter->fix_rate & BIT(7)) {
+					SET_TX_DESC_DATA_SHORT_8703B(pbuf, 1);
+				}
+				SET_TX_DESC_TX_RATE_8703B(pbuf, padapter->fix_rate & 0x7F);
+				if (!padapter->data_fb) {
+					SET_TX_DESC_DISABLE_FB_8703B(pbuf, 1);
+				}
+			}
+
+			if (pattrib->ldpc) {
+				SET_TX_DESC_DATA_LDPC_8703B(pbuf, 1);
+			}
+
+			if (pattrib->stbc) {
+				SET_TX_DESC_DATA_STBC_8703B(pbuf, 1);
+			}
+
+#ifdef CONFIG_CMCC_TEST
+			SET_TX_DESC_DATA_SHORT_8703B(pbuf, 1); /* use cck short premble */
+#endif
+		}
+		else
+		{
+			// EAP data packet and ARP packet.
+			// Use the 1M data rate to send the EAP/ARP packet.
+			// This will maybe make the handshake smooth.
+
+			SET_TX_DESC_AGG_BREAK_8703B(pbuf, 1);
+			SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
+			if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) {
+				SET_TX_DESC_DATA_SHORT_8703B(pbuf, 1);
+			}
+			SET_TX_DESC_TX_RATE_8703B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
+
+			DBG_8192C(FUNC_ADPT_FMT ": SP Packet(0x%04X) rate=0x%x\n",
+				FUNC_ADPT_ARG(padapter), pattrib->ether_type, MRateToHwRate(pmlmeext->tx_rate));
+		}
+
+#if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+		SET_TX_DESC_USB_TXAGG_NUM_8703B(pbuf, pxmitframe->agg_num);
+#endif
+
+#ifdef CONFIG_TDLS
+#ifdef CONFIG_XMIT_ACK
+		/* CCX-TXRPT ack for xmit mgmt frames. */
+		if (pxmitframe->ack_report) {
+			#ifdef DBG_CCX
+			DBG_8192C("%s set spe_rpt\n", __func__);
+			#endif
+			SET_TX_DESC_SPE_RPT_8703B(pbuf, 1);
+			SET_TX_DESC_SW_DEFINE_8703B(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
+		}
+#endif /* CONFIG_XMIT_ACK */
+#endif
+	}
+	else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
+	{
+//		RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __FUNCTION__));
+
+		SET_TX_DESC_MACID_8703B(pbuf, pattrib->mac_id);
+		SET_TX_DESC_QUEUE_SEL_8703B(pbuf, pattrib->qsel);
+		SET_TX_DESC_RATE_ID_8703B(pbuf, pattrib->raid);
+		SET_TX_DESC_SEQ_8703B(pbuf, pattrib->seqnum);
+		SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
+
+		SET_TX_DESC_MBSSID_8703B(pbuf, pattrib->mbssid & 0xF);
+
+		SET_TX_DESC_RETRY_LIMIT_ENABLE_8703B(pbuf, 1);
+		if (pattrib->retry_ctrl == _TRUE) {
+			SET_TX_DESC_DATA_RETRY_LIMIT_8703B(pbuf, 6);
+		} else {
+			SET_TX_DESC_DATA_RETRY_LIMIT_8703B(pbuf, 12);
+		}
+
+#ifdef CONFIG_INTEL_PROXIM
+		if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
+			DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
+			SET_TX_DESC_TX_RATE_8703B(pbuf, pattrib->rate);
+		}
+		else
+#endif
+		{
+			SET_TX_DESC_TX_RATE_8703B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
+		}
+
+#ifdef CONFIG_XMIT_ACK
+		// CCX-TXRPT ack for xmit mgmt frames.
+		if (pxmitframe->ack_report) {
+			#ifdef DBG_CCX
+			DBG_8192C("%s set spe_rpt\n", __FUNCTION__);
+			#endif
+			SET_TX_DESC_SPE_RPT_8703B(pbuf, 1);
+			SET_TX_DESC_SW_DEFINE_8703B(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
+		}
+#endif // CONFIG_XMIT_ACK
+	}
+	else if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
+	{
+		RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__));
+	}
+#ifdef CONFIG_MP_INCLUDED
+	else if (pxmitframe->frame_tag == MP_FRAMETAG)
+	{
+		RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __FUNCTION__));
+		fill_txdesc_for_mp(padapter, pbuf);
+	}
+#endif
+	else
+	{
+		RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag));
+
+		SET_TX_DESC_MACID_8703B(pbuf, pattrib->mac_id);
+		SET_TX_DESC_RATE_ID_8703B(pbuf, pattrib->raid);
+		SET_TX_DESC_QUEUE_SEL_8703B(pbuf, pattrib->qsel);
+		SET_TX_DESC_SEQ_8703B(pbuf, pattrib->seqnum);
+		SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
+		SET_TX_DESC_TX_RATE_8703B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
+	}
+
+	SET_TX_DESC_PKT_SIZE_8703B(pbuf, pattrib->last_txcmdsz);
+
+	{
+		u8 pkt_offset, offset;
+
+		pkt_offset = 0;
+		offset = TXDESC_SIZE;
+#ifdef CONFIG_USB_HCI
+		pkt_offset = pxmitframe->pkt_offset;
+		offset += (pxmitframe->pkt_offset >> 3);
+#endif // CONFIG_USB_HCI
+
+#ifdef CONFIG_TX_EARLY_MODE
+		if (pxmitframe->frame_tag == DATA_FRAMETAG) {
+			pkt_offset = 1;
+			offset += EARLY_MODE_INFO_SIZE;
+		}
+#endif // CONFIG_TX_EARLY_MODE
+
+		SET_TX_DESC_PKT_OFFSET_8703B(pbuf, pkt_offset);
+		SET_TX_DESC_OFFSET_8703B(pbuf, offset);
+	}
+
+	if (bmcst) {
+		SET_TX_DESC_BMC_8703B(pbuf, 1);
+	}
+
+	// 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
+	// (1) The sequence number of each non-Qos frame / broadcast / multicast /
+	// mgnt frame should be controled by Hw because Fw will also send null data
+	// which we cannot control when Fw LPS enable.
+	// --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
+	// (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
+	// (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
+	// 2010.06.23. Added by tynli.
+	if (!pattrib->qos_en) {
+		SET_TX_DESC_HWSEQ_EN_8703B(pbuf, 1);
+	}
+}
+
+/*
+ *	Description:
+ *
+ *	Parameters:
+ *		pxmitframe	xmitframe
+ *		pbuf		where to fill tx desc
+ */
+void rtl8703b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
+{
+	PADAPTER padapter = pxmitframe->padapter;
+	rtl8703b_fill_default_txdesc(pxmitframe, pbuf);
+
+#ifdef CONFIG_ANTENNA_DIVERSITY
+	ODM_SetTxAntByTxInfo(&GET_HAL_DATA(padapter)->odmpriv, pbuf, pxmitframe->attrib.mac_id);
+#endif // CONFIG_ANTENNA_DIVERSITY
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+	rtl8703b_cal_txdesc_chksum((struct tx_desc*)pbuf);
+#endif
+}
+
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+int reset_tsf(PADAPTER Adapter, u8 reset_port )
+{
+	u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
+	u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ?
+				REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1;
+
+	rtw_scan_abort(Adapter->pbuddy_adapter);	/*	site survey will cause reset_tsf fail	*/
+	reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt);
+	rtl8703b_reset_tsf(Adapter, reset_port);
+
+	while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) {
+		rtw_msleep_os(100);
+		loop_cnt++;
+		reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
+	}
+
+	return(loop_cnt >= 10) ? _FAIL : _TRUE;
+}
+#endif // CONFIG_TSF_RESET_OFFLOAD
+
+static void hw_var_set_monitor(PADAPTER Adapter, u8 variable, u8 *val)
+{
+	u32	value_rcr, rcr_bits;
+	u16	value_rxfltmap2;
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+	struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+
+	if (*((u8 *)val) == _HW_STATE_MONITOR_) {
+
+		/* Leave IPS */
+		rtw_pm_set_ips(Adapter, IPS_NONE);
+		LeaveAllPowerSaveMode(Adapter);
+
+		/* Receive all type */
+		rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_ACF | RCR_AMF | RCR_APP_PHYST_RXFF;
+
+		/* Append FCS */
+		rcr_bits |= RCR_APPFCS;
+
+		#if 0
+		/* 
+		   CRC and ICV packet will drop in recvbuf2recvframe()
+		   We no turn on it.
+		 */
+		rcr_bits |= (RCR_ACRC32 | RCR_AICV);
+		#endif
+
+		/* Receive all data frames */
+		value_rxfltmap2 = 0xFFFF;
+
+		value_rcr = rcr_bits;
+		rtw_write32(Adapter, REG_RCR, value_rcr);
+
+		rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);
+
+		#if 0
+		/* tx pause */
+		rtw_write8(padapter, REG_TXPAUSE, 0xFF);
+		#endif
+	} else {
+		/* do nothing */
+	}
+
+}
+
+static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8* val)
+{
+	u8 val8;
+	u8 mode = *((u8 *)val);
+	static u8 isMonitor = _FALSE;
+
+	HAL_DATA_TYPE			*pHalData = GET_HAL_DATA(padapter);
+
+	if (isMonitor == _TRUE) {
+		/* reset RCR */
+		rtw_write32(padapter, REG_RCR, pHalData->ReceiveConfig);
+		isMonitor = _FALSE;
+	}
+
+	if (mode == _HW_STATE_MONITOR_) {
+		isMonitor = _TRUE;
+		/* set net_type */
+		Set_MSR(padapter, _HW_STATE_NOLINK_);
+
+		hw_var_set_monitor(padapter, variable, val);
+		return;
+	}
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->iface_type == IFACE_PORT1)
+	{
+		// disable Port1 TSF update
+		val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+		val8 |= DIS_TSF_UDT;
+		rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+		
+		Set_MSR(padapter, mode);
+		
+		DBG_871X("#### %s()-%d iface_type(%d) mode=%d ####\n",
+			__FUNCTION__, __LINE__, padapter->iface_type, mode);
+
+		if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
+		{
+			if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
+			{
+				StopTxBeacon(padapter);
+#ifdef CONFIG_PCI_HCI
+				UpdateInterruptMask8703BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
+#else // !CONFIG_PCI_HCI
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN	
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT	
+				rtw_write8(padapter, REG_DRVERLYINT, 0x05);//restore early int time to 5ms
+				UpdateInterruptMask8703BU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8703B);
+#endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+				UpdateInterruptMask8703BU(padapter, _TRUE ,0, (IMR_TXBCN0ERR_8703B|IMR_TXBCN0OK_8703B));
+#endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+
+#endif // CONFIG_INTERRUPT_BASED_TXBCN
+#endif // !CONFIG_PCI_HCI
+			}
+
+			// disable atim wnd and disable beacon function
+			rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|DIS_ATIM);
+		}
+		else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
+		{
+			ResumeTxBeacon(padapter);
+			rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
+		}
+		else if (mode == _HW_STATE_AP_)
+		{
+#ifdef CONFIG_PCI_HCI
+			UpdateInterruptMask8703BE(padapter, RT_BCN_INT_MASKS, 0, 0, 0);
+#else // !CONFIG_PCI_HCI
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+
+#ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+			UpdateInterruptMask8703BU(padapter, _TRUE, IMR_BCNDMAINT0_8703B, 0);
+#endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR	
+			UpdateInterruptMask8703BU(padapter, _TRUE, (IMR_TXBCN0ERR_8703B|IMR_TXBCN0OK_8703B), 0);
+#endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+
+#endif // CONFIG_INTERRUPT_BASED_TXBCN
+#endif // !CONFIG_PCI_HCI
+
+			ResumeTxBeacon(padapter);
+
+			rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|DIS_BCNQ_SUB);
+
+			// Set RCR
+			//rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
+			//rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
+			rtw_write32(padapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
+			// enable to rx data frame				
+			rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
+			// enable to rx ps-poll
+			rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
+
+			// Beacon Control related register for first time 
+			rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms		
+
+			//rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
+			rtw_write8(padapter, REG_ATIMWND_1, 0x0a); // 10ms for port1
+			rtw_write16(padapter, REG_BCNTCFG, 0x00);
+			rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
+			rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
+	
+			// reset TSF2	
+			rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
+
+			// enable BCN1 Function for if2
+			// don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received)
+			rtw_write8(padapter, REG_BCN_CTRL_1, (DIS_TSF_UDT|EN_BCN_FUNCTION | EN_TXBCN_RPT|DIS_BCNQ_SUB));
+
+			//SW_BCN_SEL - Port1
+			//rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2)|BIT4);
+			rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
+			
+			// select BCN on port 1
+			rtw_write8(padapter, REG_CCK_CHECK_8703B,
+				(rtw_read8(padapter, REG_CCK_CHECK_8703B)|BIT_BCN_PORT_SEL));
+			
+			if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
+			{
+				val8 = rtw_read8(padapter, REG_BCN_CTRL);
+				val8 &= ~EN_BCN_FUNCTION;
+				rtw_write8(padapter, REG_BCN_CTRL, val8);
+			}
+
+			//BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked
+			//rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1)|BIT(5));
+			//rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(3));
+					
+			//dis BCN0 ATIM  WND if if1 is station
+			rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|DIS_ATIM);
+
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+			// Reset TSF for STA+AP concurrent mode
+			if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)))
+			{
+				if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
+					DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
+						__FUNCTION__, __LINE__);
+			}
+#endif // CONFIG_TSF_RESET_OFFLOAD
+		}
+	}
+	else //else for port0
+#endif // CONFIG_CONCURRENT_MODE
+	{
+		// disable Port0 TSF update
+		val8 = rtw_read8(padapter, REG_BCN_CTRL);
+		val8 |= DIS_TSF_UDT;
+		rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+		// set net_type
+		Set_MSR(padapter, mode);
+		DBG_871X("#### %s() -%d iface_type(0) mode = %d ####\n", __FUNCTION__, __LINE__, mode);
+
+		if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
+		{
+#ifdef CONFIG_CONCURRENT_MODE
+			if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))		
+#endif // CONFIG_CONCURRENT_MODE
+			{
+				StopTxBeacon(padapter);
+#ifdef CONFIG_PCI_HCI
+				UpdateInterruptMask8703BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
+#else // !CONFIG_PCI_HCI
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+				rtw_write8(padapter, REG_DRVERLYINT, 0x05); // restore early int time to 5ms
+				UpdateInterruptMask8812AU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8703B);
+#endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+				UpdateInterruptMask8812AU(padapter,_TRUE ,0, (IMR_TXBCN0ERR_8703B|IMR_TXBCN0OK_8703B));
+#endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+
+#endif // CONFIG_INTERRUPT_BASED_TXBCN
+#endif // !CONFIG_PCI_HCI
+			}
+
+			// disable atim wnd
+			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM);
+			//rtw_write8(padapter,REG_BCN_CTRL, 0x18);
+		}
+		else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
+		{
+			ResumeTxBeacon(padapter);
+			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
+		}
+		else if (mode == _HW_STATE_AP_)
+		{
+#ifdef CONFIG_PCI_HCI
+			UpdateInterruptMask8703BE( padapter, RT_BCN_INT_MASKS, 0, 0, 0);
+#else // !CONFIG_PCI_HCI
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+			UpdateInterruptMask8703BU(padapter, _TRUE ,IMR_BCNDMAINT0_8703B, 0);
+#endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+			UpdateInterruptMask8703BU(padapter,_TRUE ,(IMR_TXBCN0ERR_8703B|IMR_TXBCN0OK_8703B), 0);
+#endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+
+#endif // CONFIG_INTERRUPT_BASED_TXBCN
+#endif
+
+			ResumeTxBeacon(padapter);
+
+			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|DIS_BCNQ_SUB);
+
+			//Set RCR
+			//rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
+			//rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
+			rtw_write32(padapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
+			//enable to rx data frame
+			rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
+			//enable to rx ps-poll
+			rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
+
+			//Beacon Control related register for first time
+			rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms			
+			
+			//rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
+			rtw_write8(padapter, REG_ATIMWND, 0x0a); // 10ms
+			rtw_write16(padapter, REG_BCNTCFG, 0x00);
+			rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
+			rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
+
+			//reset TSF
+			rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
+	
+			//enable BCN0 Function for if1
+			//don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received)
+			rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT|EN_BCN_FUNCTION|EN_TXBCN_RPT|DIS_BCNQ_SUB));
+		
+			//SW_BCN_SEL - Port0
+			//rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4);
+			rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
+			
+			// select BCN on port 0
+			rtw_write8(padapter, REG_CCK_CHECK_8703B,
+				(rtw_read8(padapter, REG_CCK_CHECK_8703B)& ~BIT_BCN_PORT_SEL));				
+
+#ifdef CONFIG_CONCURRENT_MODE
+			if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
+			{
+				val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+				val8 &= ~EN_BCN_FUNCTION;
+				rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+			}
+#endif // CONFIG_CONCURRENT_MODE
+
+			// dis BCN1 ATIM  WND if if2 is station
+			val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+			val8 |= DIS_ATIM;
+			rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+			// Reset TSF for STA+AP concurrent mode
+			if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)))
+			{
+				if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
+					DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
+						__FUNCTION__, __LINE__);
+			}
+#endif	// CONFIG_TSF_RESET_OFFLOAD
+		}
+	}
+}
+
+static void hw_var_set_macaddr(PADAPTER padapter, u8 variable, u8 *val)
+{
+	u8 idx = 0;
+	u32 reg_macid;
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->iface_type == IFACE_PORT1)
+	{
+		reg_macid = REG_MACID1;
+	}
+	else
+#endif
+	{
+		reg_macid = REG_MACID;
+	}
+
+	for (idx = 0 ; idx < 6; idx++)
+	{
+		rtw_write8(GET_PRIMARY_ADAPTER(padapter), (reg_macid+idx), val[idx]);
+	}
+}
+
+static void hw_var_set_bssid(PADAPTER padapter, u8 variable, u8 *val)
+{
+	u8	idx = 0;
+	u32 reg_bssid;
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->iface_type == IFACE_PORT1)
+	{
+		reg_bssid = REG_BSSID1;
+	}
+	else
+#endif
+	{
+		reg_bssid = REG_BSSID;
+	}
+
+	for (idx = 0 ; idx < 6; idx++)
+	{
+		rtw_write8(padapter, (reg_bssid+idx), val[idx]);
+	}
+}
+
+static void hw_var_set_bcn_func(PADAPTER padapter, u8 variable, u8 *val)
+{
+	u32 bcn_ctrl_reg;
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->iface_type == IFACE_PORT1)
+	{
+		bcn_ctrl_reg = REG_BCN_CTRL_1;
+	}
+	else
+#endif
+	{
+		bcn_ctrl_reg = REG_BCN_CTRL;
+	}
+
+	if (*(u8*)val)
+	{
+		rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
+	}
+	else
+	{
+		u8 val8;
+		val8 = rtw_read8(padapter, bcn_ctrl_reg);
+		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
+#ifdef CONFIG_BT_COEXIST
+		// Always enable port0 beacon function for PSTDMA
+		if (REG_BCN_CTRL == bcn_ctrl_reg)
+			val8 |= EN_BCN_FUNCTION;
+#endif
+		rtw_write8(padapter, bcn_ctrl_reg, val8);
+	}
+}
+
+static void hw_var_set_correct_tsf(PADAPTER padapter, u8 variable, u8* val)
+{
+	u8 val8;
+	u64	tsf;
+	struct mlme_ext_priv *pmlmeext;
+	struct mlme_ext_info *pmlmeinfo;
+
+
+	pmlmeext = &padapter->mlmeextpriv;
+	pmlmeinfo = &pmlmeext->mlmext_info;
+	
+	tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us
+
+	if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
+		((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
+	{
+		StopTxBeacon(padapter);
+	}
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->iface_type == IFACE_PORT1)
+	{
+		// disable related TSF function
+		val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+		val8 &= ~EN_BCN_FUNCTION;
+		rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+
+		rtw_write32(padapter, REG_TSFTR1, tsf);
+		rtw_write32(padapter, REG_TSFTR1+4, tsf>>32);
+
+
+		// enable related TSF function
+		val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+		val8 |= EN_BCN_FUNCTION;
+		rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+
+		// Update buddy port's TSF if it is SoftAP for beacon TX issue!
+		if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
+			&& check_buddy_fwstate(padapter, WIFI_AP_STATE)
+			)
+		{
+			// disable related TSF function
+			val8 = rtw_read8(padapter, REG_BCN_CTRL);
+			val8 &= ~EN_BCN_FUNCTION;
+			rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+			rtw_write32(padapter, REG_TSFTR, tsf);
+			rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
+
+			// enable related TSF function
+			val8 = rtw_read8(padapter, REG_BCN_CTRL);
+			val8 |= EN_BCN_FUNCTION;
+			rtw_write8(padapter, REG_BCN_CTRL, val8);
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+			// Update buddy port's TSF(TBTT) if it is SoftAP for beacon TX issue!
+			if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
+				DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
+					__FUNCTION__, __LINE__);
+
+#endif // CONFIG_TSF_RESET_OFFLOAD
+		}
+	}
+	else
+#endif // CONFIG_CONCURRENT_MODE
+	{
+		// disable related TSF function
+		val8 = rtw_read8(padapter, REG_BCN_CTRL);
+		val8 &= ~EN_BCN_FUNCTION;
+		rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+		rtw_write32(padapter, REG_TSFTR, tsf);
+		rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
+
+		// enable related TSF function
+		val8 = rtw_read8(padapter, REG_BCN_CTRL);
+		val8 |= EN_BCN_FUNCTION;
+		rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+#ifdef CONFIG_CONCURRENT_MODE
+		// Update buddy port's TSF if it is SoftAP for beacon TX issue!
+		if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
+			&& check_buddy_fwstate(padapter, WIFI_AP_STATE))
+		{
+			// disable related TSF function
+			val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+			val8 &= ~EN_BCN_FUNCTION;
+			rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+
+			rtw_write32(padapter, REG_TSFTR1, tsf);
+			rtw_write32(padapter, REG_TSFTR1+4, tsf>>32);
+
+			// enable related TSF function
+			val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+			val8 |= EN_BCN_FUNCTION;
+			rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+			// Update buddy port's TSF if it is SoftAP for beacon TX issue!
+			if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
+			{
+				DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
+					__FUNCTION__, __LINE__);
+			}
+#endif // CONFIG_TSF_RESET_OFFLOAD
+		}
+#endif // CONFIG_CONCURRENT_MODE
+	}
+
+	if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
+		|| ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
+	{
+		ResumeTxBeacon(padapter);
+	}
+}
+
+static void hw_var_set_mlme_disconnect(PADAPTER padapter, u8 variable, u8 *val)
+{
+	u8 val8;
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
+#endif
+	{
+		// Set RCR to not to receive data frame when NO LINK state
+		//rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
+		// reject all data frames
+		rtw_write16(padapter, REG_RXFLTMAP2, 0);
+	}
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->iface_type == IFACE_PORT1)
+	{
+		// reset TSF1
+		rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
+
+		// disable update TSF1
+		val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+		val8 |= DIS_TSF_UDT;
+		rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+		
+		// disable Port1's beacon function
+		val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+		val8 &= ~EN_BCN_FUNCTION;
+		rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+	}
+	else
+#endif
+	{
+		// reset TSF
+		rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
+
+		// disable update TSF
+		val8 = rtw_read8(padapter, REG_BCN_CTRL);
+		val8 |= DIS_TSF_UDT;
+		rtw_write8(padapter, REG_BCN_CTRL, val8);
+	}
+}
+
+static void hw_var_set_mlme_sitesurvey(PADAPTER padapter, u8 variable, u8* val)
+{
+	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+	u32	value_rcr, rcr_clear_bit, reg_bcn_ctl;
+	u16	value_rxfltmap2;
+	u8 val8;
+	PHAL_DATA_TYPE pHalData;
+	struct mlme_priv *pmlmepriv;
+	u8 ap_num;
+
+	rtw_dev_iface_status(padapter, NULL, NULL, NULL, &ap_num, NULL);
+
+	pHalData = GET_HAL_DATA(padapter);
+	pmlmepriv = &padapter->mlmepriv;
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (padapter->iface_type == IFACE_PORT1)
+		reg_bcn_ctl = REG_BCN_CTRL_1;
+	else
+#endif
+		reg_bcn_ctl = REG_BCN_CTRL;
+
+#ifdef CONFIG_FIND_BEST_CHANNEL
+	rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA);
+
+	/* Receive all data frames */
+	value_rxfltmap2 = 0xFFFF;
+#else // CONFIG_FIND_BEST_CHANNEL
+
+	rcr_clear_bit = RCR_CBSSID_BCN;
+
+	// config RCR to receive different BSSID & not to receive data frame
+	value_rxfltmap2 = 0;
+
+#endif // CONFIG_FIND_BEST_CHANNEL
+
+	if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
+#ifdef CONFIG_CONCURRENT_MODE
+		|| (check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE)
+#endif
+		)
+	{
+		rcr_clear_bit = RCR_CBSSID_BCN;
+	}
+#ifdef CONFIG_TDLS
+	// TDLS will clear RCR_CBSSID_DATA bit for connection.
+	else if (padapter->tdlsinfo.link_established == _TRUE)
+	{
+		rcr_clear_bit = RCR_CBSSID_BCN;
+	}
+#endif // CONFIG_TDLS
+
+	value_rcr = rtw_read32(padapter, REG_RCR);
+
+	if (*((u8*)val))
+	{
+		// under sitesurvey
+		value_rcr &= ~(rcr_clear_bit);
+		rtw_write32(padapter, REG_RCR, value_rcr);
+
+		rtw_write16(padapter, REG_RXFLTMAP2, value_rxfltmap2);
+
+		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
+		{
+			// disable update TSF
+			val8 = rtw_read8(padapter, reg_bcn_ctl);
+			val8 |= DIS_TSF_UDT;
+			rtw_write8(padapter, reg_bcn_ctl, val8);
+		}
+
+		// Save orignal RRSR setting.
+		pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR);
+
+		if (ap_num)
+			StopTxBeacon(padapter);
+	}
+	else
+	{
+		// sitesurvey done
+		if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))
+#ifdef CONFIG_CONCURRENT_MODE
+			|| check_buddy_fwstate(padapter, (_FW_LINKED|WIFI_AP_STATE))
+#endif
+			)
+		{
+			// enable to rx data frame
+			rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
+		}
+
+		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
+		{
+			// enable update TSF
+			val8 = rtw_read8(padapter, reg_bcn_ctl);
+			val8 &= ~DIS_TSF_UDT;
+			rtw_write8(padapter, reg_bcn_ctl, val8);
+		}
+
+		value_rcr |= rcr_clear_bit;
+		rtw_write32(padapter, REG_RCR, value_rcr);
+
+		// Restore orignal RRSR setting.
+		rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR);
+
+		if (ap_num) {
+			int i;
+			_adapter *iface;
+
+			ResumeTxBeacon(padapter);
+			for (i = 0; i < dvobj->iface_nums; i++) {
+				iface = dvobj->padapters[i];
+				if (!iface)
+					continue;
+
+				if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
+					&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
+				) {
+					iface->mlmepriv.update_bcn = _TRUE;
+					#ifndef CONFIG_INTERRUPT_BASED_TXBCN
+					#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+					tx_beacon_hdl(iface, NULL);
+					#endif
+					#endif
+					
+				}
+			}
+		}
+	}
+}
+
+static void hw_var_set_mlme_join(PADAPTER padapter, u8 variable, u8 *val)
+{
+	u8 val8;
+	u16 val16;
+	u32 val32;
+	u8 RetryLimit;
+	u8 type;
+	PHAL_DATA_TYPE pHalData;
+	struct mlme_priv *pmlmepriv;
+
+	RetryLimit = 0x30;
+	type = *(u8*)val;
+	pHalData = GET_HAL_DATA(padapter);
+	pmlmepriv = &padapter->mlmepriv;
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if (type == 0)
+	{
+		// prepare to join
+		if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
+			check_buddy_fwstate(padapter, _FW_LINKED))
+		{
+			StopTxBeacon(padapter);
+		}
+
+		// enable to rx data frame.Accept all data frame
+		rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
+
+		if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
+		{
+			val32 = rtw_read32(padapter, REG_RCR);
+			val32 |= RCR_CBSSID_BCN;
+			rtw_write32(padapter, REG_RCR, val32);
+		}
+		else
+		{
+			val32 = rtw_read32(padapter, REG_RCR);
+			val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
+			rtw_write32(padapter, REG_RCR, val32);
+		}
+
+		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
+		{
+			RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
+		}
+		else // Ad-hoc Mode
+		{
+			RetryLimit = 0x7;
+		}
+	}
+	else if (type == 1)
+	{
+		// joinbss_event call back when join res < 0
+		if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
+			rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
+
+		if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
+			check_buddy_fwstate(padapter, _FW_LINKED))
+		{
+			ResumeTxBeacon(padapter);
+
+			// reset TSF 1/2 after ResumeTxBeacon
+			rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
+		}
+	}
+	else if (type == 2)
+	{
+		// sta add event call back
+
+		// enable update TSF
+		if (padapter->iface_type == IFACE_PORT1)
+		{
+			val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
+			val8 &= ~DIS_TSF_UDT;
+			rtw_write8(padapter, REG_BCN_CTRL_1, val8);
+		}
+		else
+		{
+			val8 = rtw_read8(padapter, REG_BCN_CTRL);
+			val8 &= ~DIS_TSF_UDT;
+			rtw_write8(padapter, REG_BCN_CTRL, val8);
+		}
+
+		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
+		{
+			rtw_write8(padapter, 0x542 ,0x02);
+			RetryLimit = 0x7;
+		}
+
+		if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
+			check_buddy_fwstate(padapter, _FW_LINKED))
+		{
+			ResumeTxBeacon(padapter);
+
+			// reset TSF 1/2 after ResumeTxBeacon
+			rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
+		}
+	}
+
+	val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+	rtw_write16(padapter, REG_RL, val16);
+#else // !CONFIG_CONCURRENT_MODE
+	if (type == 0) // prepare to join
+	{
+		//enable to rx data frame.Accept all data frame
+		//rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
+		rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
+
+		val32 = rtw_read32(padapter, REG_RCR);
+		if (padapter->in_cta_test)
+			val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);//| RCR_ADF
+		else
+			val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
+		rtw_write32(padapter, REG_RCR, val32);
+
+		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
+		{
+			RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
+		}
+		else // Ad-hoc Mode
+		{
+			RetryLimit = 0x7;
+		}
+	}
+	else if (type == 1) //joinbss_event call back when join res < 0
+	{
+		rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
+	}
+	else if (type == 2) //sta add event call back
+	{
+		//enable update TSF
+		val8 = rtw_read8(padapter, REG_BCN_CTRL);
+		val8 &= ~DIS_TSF_UDT;
+		rtw_write8(padapter, REG_BCN_CTRL, val8);
+
+		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
+		{
+			RetryLimit = 0x7;
+		}
+	}
+
+	val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+	rtw_write16(padapter, REG_RL, val16);
+#endif // !CONFIG_CONCURRENT_MODE
+}
+
+void CCX_FwC2HTxRpt_8703b(PADAPTER padapter, u8 *pdata, u8 len)
+{
+	u8 seq_no;
+	
+#define	GET_8703B_C2H_TX_RPT_LIFE_TIME_OVER(_Header)	LE_BITS_TO_1BYTE((_Header + 0), 6, 1)
+#define	GET_8703B_C2H_TX_RPT_RETRY_OVER(_Header)	LE_BITS_TO_1BYTE((_Header + 0), 7, 1)
+
+	//DBG_871X("%s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, 
+	//		*pdata, *(pdata+1), *(pdata+2), *(pdata+3), *(pdata+4), *(pdata+5), *(pdata+6), *(pdata+7));
+
+	seq_no = *(pdata+6);
+
+#ifdef CONFIG_XMIT_ACK
+	if (GET_8703B_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8703B_C2H_TX_RPT_LIFE_TIME_OVER(pdata)) {
+		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
+	}
+/*	
+	else if(seq_no != padapter->xmitpriv.seq_no) {
+		DBG_871X("tx_seq_no=%d, rpt_seq_no=%d\n", padapter->xmitpriv.seq_no, seq_no);
+		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
+	} 
+*/	
+	else {
+		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
+	}
+#endif
+}
+
+s32 c2h_id_filter_ccx_8703b(u8 *buf)
+{
+	struct c2h_evt_hdr_88xx *c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
+	s32 ret = _FALSE;
+	if (c2h_evt->id == C2H_CCX_TX_RPT)
+		ret = _TRUE;
+	
+	return ret;
+}
+
+
+s32 c2h_handler_8703b(PADAPTER padapter, u8 *buf)
+{
+	struct c2h_evt_hdr_88xx *pC2hEvent = (struct c2h_evt_hdr_88xx *)buf;
+	PHAL_DATA_TYPE	pHalData=GET_HAL_DATA(padapter);
+	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	s32 ret = _SUCCESS;
+	u8 index = 0;
+
+	if (pC2hEvent == NULL) {
+		DBG_8192C("%s(): pC2hEventis NULL\n",__FUNCTION__);
+		ret = _FAIL;
+		goto exit;
+	}
+
+	switch (pC2hEvent->id) {
+	case C2H_DBG:
+		RT_TRACE(_module_hal_init_c_, _drv_info_, ("c2h_handler_8703b: %s\n", pC2hEvent->payload));
+		break;
+
+	case C2H_CCX_TX_RPT:
+		/*CCX_FwC2HTxRpt(padapter, QueueID, pC2hEvent->payload); */
+		break;
+
+#ifdef CONFIG_BT_COEXIST
+	case C2H_BT_INFO:
+		rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
+		break;
+	case C2H_BT_MP_INFO:
+		DBG_8192C("%s, C2H_BT_MP_INFO pC2hEvent->plen=%d\n", __func__, pC2hEvent->plen);
+		rtw_btcoex_BtMpRptNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
+		break;
+	case C2H_BT_SCOREBOARD_STATUS:
+		rtw_btcoex_ScoreBoardStatusNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
+		break;
+#endif
+
+	default:
+		break;
+	}
+
+	// Clear event to notify FW we have read the command.
+	// Note:
+	//	If this field isn't clear, the FW won't update the next command message.
+//	rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
+exit:
+	return ret;
+}
+
+static void process_c2h_event(PADAPTER padapter, PC2H_EVT_HDR pC2hEvent, u8 *c2hBuf)
+{
+	u8				index = 0;
+	PHAL_DATA_TYPE	pHalData=GET_HAL_DATA(padapter);
+	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
+	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	PDM_ODM_T			pDM_Odm = &pHalData->odmpriv;
+
+	if (c2hBuf == NULL) {
+		DBG_8192C("%s c2hbuff is NULL\n",__FUNCTION__);
+		return;
+	}
+
+	switch (pC2hEvent->CmdID) {
+	case C2H_CCX_TX_RPT:
+		CCX_FwC2HTxRpt_8703b(padapter, c2hBuf, pC2hEvent->CmdLen);
+		break;
+
+#ifdef CONFIG_BT_COEXIST
+	case C2H_BT_INFO:
+		rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
+		break;
+	case C2H_BT_MP_INFO:
+		rtw_btcoex_BtMpRptNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
+		break;
+	case C2H_BT_SCOREBOARD_STATUS:
+		rtw_btcoex_ScoreBoardStatusNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
+		break;
+#endif
+
+#ifdef CONFIG_FW_C2H_DEBUG
+	case C2H_EXTEND:
+		Debug_FwC2H(padapter, c2hBuf, pC2hEvent->CmdLen);
+		break;
+#endif /* CONFIG_FW_C2H_DEBUG */
+
+	default:
+		if (!(phydm_c2H_content_parsing(pDM_Odm, pC2hEvent->CmdID, pC2hEvent->CmdLen, c2hBuf)))
+			RT_TRACE(_module_hal_init_c_, _drv_info_, ("%s: [WARNING] unknown C2H(0x%02x)\n", __func__, c2hCmdId));
+			
+		break;
+	}
+
+#ifndef CONFIG_C2H_PACKET_EN
+	// Clear event to notify FW we have read the command.
+	// Note:
+	//	If this field isn't clear, the FW won't update the next command message.
+	rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
+#endif
+}
+
+#ifdef CONFIG_C2H_PACKET_EN
+
+static void C2HPacketHandler_8703B(PADAPTER padapter, u8 *pbuffer, u16 length)
+{
+	C2H_EVT_HDR 	C2hEvent;
+	u8 *tmpBuf=NULL;
+#ifdef CONFIG_WOWLAN
+	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+	
+	if(pwrpriv->wowlan_mode == _TRUE)
+	{
+		DBG_871X("%s(): return because wowolan_mode==TRUE! CMDID=%d\n", __func__, pbuffer[0]);
+		return;
+	}
+#endif
+	C2hEvent.CmdID = pbuffer[0];
+	C2hEvent.CmdSeq = pbuffer[1];
+	C2hEvent.CmdLen = length - 2;
+	tmpBuf = pbuffer + 2;
+
+	//DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n",
+	//		__func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq);
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HPacketHandler_8703B(): Command Content:\n", tmpBuf, C2hEvent.CmdLen);
+	
+	process_c2h_event(padapter, &C2hEvent, tmpBuf);
+	//c2h_handler_8703b(padapter,&C2hEvent);
+	return;
+}
+
+void rtl8703b_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length)
+{
+	C2H_EVT_HDR C2hEvent;
+	u8 *pdata;
+
+
+	if (length == 0)
+		return;
+
+	C2hEvent.CmdID = pbuf[0];
+	C2hEvent.CmdSeq = pbuf[1];
+	C2hEvent.CmdLen = length - 2;
+	pdata = pbuf + 2;
+
+	DBG_8192C("%s: C2H, ID=%d seq=%d len=%d\n",
+		__FUNCTION__, C2hEvent.CmdID, C2hEvent.CmdSeq, C2hEvent.CmdLen);
+
+	switch (C2hEvent.CmdID) {
+	case C2H_CCX_TX_RPT:
+#ifdef CONFIG_BT_COEXIST
+	case C2H_BT_MP_INFO:
+#endif /* CONFIG_BT_COEXIST */
+#ifdef CONFIG_FW_C2H_DEBUG
+	case C2H_EXTEND:
+#endif // CONFIG_FW_C2H_DEBUG
+		process_c2h_event(padapter, &C2hEvent, pdata);
+		break;
+
+	default:
+		pdata = rtw_zmalloc(length);
+		if (pdata == NULL)
+			break;
+		_rtw_memcpy(pdata, pbuf, length);
+		if (rtw_c2h_packet_wk_cmd(padapter, pdata, length) == _FAIL)
+			rtw_mfree(pdata, length);
+		break;
+	}
+}
+
+#else // !CONFIG_C2H_PACKET_EN
+//
+//C2H event format:
+// Field	 TRIGGER		CONTENT    CMD_SEQ	CMD_LEN 	 CMD_ID
+// BITS  [127:120]	[119:16]	  [15:8]		  [7:4] 	   [3:0]
+//2009.10.08. by tynli.
+static void C2HCommandHandler(PADAPTER padapter)
+{
+	C2H_EVT_HDR 	C2hEvent;
+#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+
+	u8				*tmpBuf = NULL;
+	u8				index = 0;
+	u8				bCmdMsgReady = _FALSE;
+	u8				U1bTmp = 0;
+//	u8				QueueID = 0;
+
+	_rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR));
+
+	C2hEvent.CmdID = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8703B);
+	C2hEvent.CmdLen = rtw_read8(padapter, REG_C2HEVT_CMD_LEN_8703B);
+	C2hEvent.CmdSeq = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8703B + 1);
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "C2HCommandHandler(): ",
+		&C2hEvent , sizeof(C2hEvent));
+
+	U1bTmp = rtw_read8(padapter, REG_C2HEVT_CLEAR);
+	DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n",
+			__func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq);
+
+	if (U1bTmp == C2H_EVT_HOST_CLOSE)
+	{
+		// Not ready.
+		return;
+	}
+	else if (U1bTmp == C2H_EVT_FW_CLOSE)
+	{
+		bCmdMsgReady = _TRUE;
+	}
+	else
+	{
+		// Not a valid value, reset the clear event.
+		goto exit;
+	}
+
+	if(C2hEvent.CmdLen == 0)
+		goto exit;
+	tmpBuf = rtw_zmalloc(C2hEvent.CmdLen);
+	if (tmpBuf == NULL)
+		goto exit;
+
+	// Read the content
+	for (index = 0; index < C2hEvent.CmdLen; index++)
+	{
+		tmpBuf[index] = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8703B + 2 + index);
+	}
+
+	RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HCommandHandler(): Command Content:\n", tmpBuf, C2hEvent.CmdLen);
+
+	//process_c2h_event(padapter,&C2hEvent, tmpBuf);
+	c2h_handler_8703b(padapter,&C2hEvent);
+	if (tmpBuf)
+		rtw_mfree(tmpBuf, C2hEvent.CmdLen);
+#endif // CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
+
+#ifdef CONFIG_USB_HCI
+	HAL_DATA_TYPE	*pHalData=GET_HAL_DATA(padapter);
+
+	_rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR));
+	C2hEvent.CmdID = pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF;
+	C2hEvent.CmdLen = (pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF0) >> 4;
+	C2hEvent.CmdSeq =pHalData->C2hArray[USB_C2H_SEQ_OFFSET];
+	c2h_handler_8703b(padapter,(u8 *)&C2hEvent);
+	//process_c2h_event(padapter,&C2hEvent,&pHalData->C2hArray[USB_C2H_EVENT_OFFSET]);
+#endif // CONFIG_USB_HCI
+
+	//REG_C2HEVT_CLEAR have done in process_c2h_event
+	return;
+exit:
+	rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
+	return;
+}
+
+#endif // !CONFIG_C2H_PACKET_EN
+
+void SetHwReg8703B(PADAPTER padapter, u8 variable, u8 *val)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
+	u8 val8;
+	u16 val16;
+	u32 val32;
+
+_func_enter_;
+
+	switch (variable)
+	{
+		case HW_VAR_MEDIA_STATUS:
+			val8 = rtw_read8(padapter, MSR) & 0x0c;
+			val8 |= *val;
+			rtw_write8(padapter, MSR, val8);
+			break;
+
+		case HW_VAR_MEDIA_STATUS1:
+			val8 = rtw_read8(padapter, MSR) & 0x03;
+			val8 |= *val << 2;
+			rtw_write8(padapter, MSR, val8);
+			break;
+
+		case HW_VAR_SET_OPMODE:
+			hw_var_set_opmode(padapter, variable, val);
+			break;
+
+		case HW_VAR_MAC_ADDR:
+			hw_var_set_macaddr(padapter, variable, val);
+			break;
+
+		case HW_VAR_BSSID:
+			hw_var_set_bssid(padapter, variable, val);
+			break;
+
+		case HW_VAR_BASIC_RATE:
+		{
+			struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
+			u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
+			u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
+			u16 rrsr_2g_allow_mask = (RRSR_24M|RRSR_12M|RRSR_6M|RRSR_CCK_RATES);
+
+			HalSetBrateCfg(padapter, val, &BrateCfg);
+			input_b = BrateCfg;
+
+			/* apply force and allow mask */
+			BrateCfg |= rrsr_2g_force_mask;
+			BrateCfg &= rrsr_2g_allow_mask;
+			masked = BrateCfg;
+
+			#ifdef CONFIG_CMCC_TEST
+			BrateCfg |= (RRSR_11M|RRSR_5_5M|RRSR_1M); /* use 11M to send ACK */
+			BrateCfg |= (RRSR_24M|RRSR_18M|RRSR_12M); //CMCC_OFDM_ACK 12/18/24M
+			#endif
+
+			/* IOT consideration */
+			if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
+				/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
+				if((BrateCfg & (RRSR_24M|RRSR_12M|RRSR_6M)) == 0)
+					BrateCfg |= RRSR_6M;
+			}
+			ioted = BrateCfg;
+
+			pHalData->BasicRateSet = BrateCfg;
+
+			DBG_8192C("HW_VAR_BASIC_RATE: %#x -> %#x -> %#x\n", input_b, masked, ioted);
+
+			// Set RRSR rate table.
+			rtw_write16(padapter, REG_RRSR, BrateCfg);
+			rtw_write8(padapter, REG_RRSR+2, rtw_read8(padapter, REG_RRSR+2)&0xf0);
+		}
+			break;
+
+		case HW_VAR_TXPAUSE:
+			rtw_write8(padapter, REG_TXPAUSE, *val);
+			break;
+
+		case HW_VAR_BCN_FUNC:
+			hw_var_set_bcn_func(padapter, variable, val);
+			break;
+
+		case HW_VAR_CORRECT_TSF:
+			hw_var_set_correct_tsf(padapter, variable, val);
+			break;
+
+		case HW_VAR_CHECK_BSSID:
+			{
+				u32 val32;
+				val32 = rtw_read32(padapter, REG_RCR);
+				if (*val)
+					val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
+				else
+					val32 &= ~(RCR_CBSSID_DATA|RCR_CBSSID_BCN);
+				rtw_write32(padapter, REG_RCR, val32);
+			}
+			break;
+
+		case HW_VAR_MLME_DISCONNECT:
+			hw_var_set_mlme_disconnect(padapter, variable, val);
+			break;
+
+		case HW_VAR_MLME_SITESURVEY:
+			hw_var_set_mlme_sitesurvey(padapter, variable,  val);
+
+#ifdef CONFIG_BT_COEXIST
+			rtw_btcoex_ScanNotify(padapter, *val?_TRUE:_FALSE);
+#endif // CONFIG_BT_COEXIST
+			break;
+
+		case HW_VAR_MLME_JOIN:
+			hw_var_set_mlme_join(padapter, variable, val);
+
+#ifdef CONFIG_BT_COEXIST
+			switch (*val)
+			{
+				case 0:
+					// prepare to join
+					rtw_btcoex_ConnectNotify(padapter, _TRUE);
+					break;
+				case 1:
+					// joinbss_event callback when join res < 0
+					rtw_btcoex_ConnectNotify(padapter, _FALSE);
+					break;
+				case 2:
+					// sta add event callback
+//					rtw_btcoex_MediaStatusNotify(padapter, RT_MEDIA_CONNECT);
+					break;
+			}
+#endif // CONFIG_BT_COEXIST
+			break;
+
+		case HW_VAR_ON_RCR_AM:
+			val32 = rtw_read32(padapter, REG_RCR);
+			val32 |= RCR_AM;
+			rtw_write32(padapter, REG_RCR, val32);
+			DBG_8192C("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
+			break;
+
+		case HW_VAR_OFF_RCR_AM:
+			val32 = rtw_read32(padapter, REG_RCR);
+			val32 &= ~RCR_AM;
+			rtw_write32(padapter, REG_RCR, val32);
+			DBG_8192C("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
+			break;
+
+		case HW_VAR_BEACON_INTERVAL:
+			rtw_write16(padapter, REG_BCN_INTERVAL, *((u16*)val));
+			break;
+
+		case HW_VAR_SLOT_TIME:
+			rtw_write8(padapter, REG_SLOT, *val);
+			break;
+
+		case HW_VAR_RESP_SIFS:
+#if 0
+			// SIFS for OFDM Data ACK
+			rtw_write8(padapter, REG_SIFS_CTX+1, val[0]);
+			// SIFS for OFDM consecutive tx like CTS data!
+			rtw_write8(padapter, REG_SIFS_TRX+1, val[1]);
+
+			rtw_write8(padapter, REG_SPEC_SIFS+1, val[0]);
+			rtw_write8(padapter, REG_MAC_SPEC_SIFS+1, val[0]);
+
+			// 20100719 Joseph: Revise SIFS setting due to Hardware register definition change.
+			rtw_write8(padapter, REG_R2T_SIFS+1, val[0]);
+			rtw_write8(padapter, REG_T2T_SIFS+1, val[0]);
+
+#else
+			//SIFS_Timer = 0x0a0a0808;
+			//RESP_SIFS for CCK
+			rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); // SIFS_T2T_CCK (0x08)
+			rtw_write8(padapter, REG_RESP_SIFS_CCK+1, val[1]); //SIFS_R2T_CCK(0x08)
+			//RESP_SIFS for OFDM
+			rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); //SIFS_T2T_OFDM (0x0a)
+			rtw_write8(padapter, REG_RESP_SIFS_OFDM+1, val[3]); //SIFS_R2T_OFDM(0x0a)
+#endif
+			break;
+
+		case HW_VAR_ACK_PREAMBLE:
+			{
+				u8 regTmp;
+				u8 bShortPreamble = *val;
+
+				// Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily)
+				//regTmp = (pHalData->nCur40MhzPrimeSC)<<5;
+				regTmp = 0;
+				if (bShortPreamble) regTmp |= 0x80;
+				rtw_write8(padapter, REG_RRSR+2, regTmp);
+			}
+			break;
+
+		case HW_VAR_CAM_EMPTY_ENTRY:
+			{
+				u8	ucIndex = *val;
+				u8	i;
+				u32	ulCommand = 0;
+				u32	ulContent = 0;
+				u32	ulEncAlgo = CAM_AES;
+
+				for (i=0; i<CAM_CONTENT_COUNT; i++)
+				{
+					// filled id in CAM config 2 byte
+					if (i == 0)
+					{
+						ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
+						//ulContent |= CAM_VALID;
+					}
+					else
+					{
+						ulContent = 0;
+					}
+					// polling bit, and No Write enable, and address
+					ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
+					ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
+					// write content 0 is equall to mark invalid
+					rtw_write32(padapter, WCAMI, ulContent);  //delay_ms(40);
+					//RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx \n",ulContent));
+					rtw_write32(padapter, RWCAM, ulCommand);  //delay_ms(40);
+					//RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx \n",ulCommand));
+				}
+			}
+			break;
+
+		case HW_VAR_CAM_INVALID_ALL:
+			rtw_write32(padapter, RWCAM, BIT(31)|BIT(30));
+			break;
+
+		case HW_VAR_AC_PARAM_VO:
+			rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32*)val));
+			break;
+
+		case HW_VAR_AC_PARAM_VI:
+			rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32*)val));
+			break;
+
+		case HW_VAR_AC_PARAM_BE:
+			pHalData->AcParam_BE = ((u32*)(val))[0];
+			rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32*)val));
+			break;
+
+		case HW_VAR_AC_PARAM_BK:
+			rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32*)val));
+			break;
+
+		case HW_VAR_ACM_CTRL:
+			{
+				u8 ctrl = *((u8*)val);
+				u8 hwctrl = 0;
+
+				if (ctrl != 0)
+				{
+					hwctrl |= AcmHw_HwEn;
+
+					if (ctrl & BIT(1)) // BE
+						hwctrl |= AcmHw_BeqEn;
+
+					if (ctrl & BIT(2)) // VI
+						hwctrl |= AcmHw_ViqEn;
+
+					if (ctrl & BIT(3)) // VO
+						hwctrl |= AcmHw_VoqEn;
+				}
+
+				DBG_8192C("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
+				rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
+			}
+			break;
+
+		case HW_VAR_AMPDU_FACTOR:
+			{
+				u32	AMPDULen =  (*((u8 *)val));
+
+				if(AMPDULen < HT_AGG_SIZE_32K)
+					AMPDULen = (0x2000 << (*((u8 *)val))) -1;
+				else
+					AMPDULen = 0x7fff;
+
+				rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8703B, AMPDULen);
+			}
+			break;
+
+#if 0
+		case HW_VAR_RXDMA_AGG_PG_TH:
+			rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, *val);
+			break;
+#endif
+
+		case HW_VAR_H2C_FW_PWRMODE:
+			{
+				u8 psmode = *val;
+
+				// Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power
+				// saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang.
+				if (psmode != PS_MODE_ACTIVE)
+				{
+					ODM_RF_Saving(&pHalData->odmpriv, _TRUE);
+				}
+
+				//if (psmode != PS_MODE_ACTIVE)	{
+				//	rtl8703b_set_lowpwr_lps_cmd(padapter, _TRUE);
+				//} else {
+				//	rtl8703b_set_lowpwr_lps_cmd(padapter, _FALSE);
+				//}
+				rtl8703b_set_FwPwrMode_cmd(padapter, psmode);
+			}
+			break;
+		case HW_VAR_H2C_PS_TUNE_PARAM:
+			rtl8703b_set_FwPsTuneParam_cmd(padapter);
+			break;
+			
+		case HW_VAR_H2C_FW_JOINBSSRPT:
+			rtl8703b_set_FwJoinBssRpt_cmd(padapter, *val);
+			break;
+
+#ifdef CONFIG_P2P
+		case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
+			rtl8703b_set_p2p_ps_offload_cmd(padapter, *val);
+			break;
+#endif //CONFIG_P2P
+#ifdef CONFIG_TDLS
+		case HW_VAR_TDLS_WRCR:
+			rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)&(~RCR_CBSSID_DATA ));
+			break;
+		case HW_VAR_TDLS_RS_RCR:
+			rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|(RCR_CBSSID_DATA));
+			break;
+#endif //CONFIG_TDLS
+
+#ifdef CONFIG_ANTENNA_DIVERSITY
+
+		case HW_VAR_ANTENNA_DIVERSITY_SELECT:
+			{
+				u8	Optimum_antenna = (*(u8 *)val);
+				u8	Ant;
+				/*switch antenna to Optimum_antenna*/
+				/*DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");*/
+				if (pHalData->CurAntenna !=  Optimum_antenna) {					
+					Ant = (Optimum_antenna == 2) ? MAIN_ANT : AUX_ANT;
+					ODM_UpdateRxIdleAnt(&pHalData->odmpriv, Ant);
+						
+					pHalData->CurAntenna = Optimum_antenna;
+					/*DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");*/
+				}
+			}
+			break;
+#endif
+
+		case HW_VAR_EFUSE_USAGE:
+			pHalData->EfuseUsedPercentage = *val;
+			break;
+
+		case HW_VAR_EFUSE_BYTES:
+			pHalData->EfuseUsedBytes = *((u16*)val);
+			break;
+
+		case HW_VAR_EFUSE_BT_USAGE:
+#ifdef HAL_EFUSE_MEMORY
+			pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
+#endif
+			break;
+
+		case HW_VAR_EFUSE_BT_BYTES:
+#ifdef HAL_EFUSE_MEMORY
+			pHalData->EfuseHal.BTEfuseUsedBytes = *((u16*)val);
+#else
+			BTEfuseUsedBytes = *((u16*)val);
+#endif
+			break;
+
+		case HW_VAR_FIFO_CLEARN_UP:
+			{
+				#define RW_RELEASE_EN		BIT(18)
+				#define RXDMA_IDLE			BIT(17)
+
+				struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+				u8 trycnt = 100;
+
+				// pause tx
+				rtw_write8(padapter, REG_TXPAUSE, 0xff);
+
+				// keep sn
+				padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
+
+				if (pwrpriv->bkeepfwalive != _TRUE)
+				{
+					/* RX DMA stop */
+					val32 = rtw_read32(padapter, REG_RXPKT_NUM);
+					val32 |= RW_RELEASE_EN;
+					rtw_write32(padapter, REG_RXPKT_NUM, val32);
+					do {
+						val32 = rtw_read32(padapter, REG_RXPKT_NUM);
+						val32 &= RXDMA_IDLE;
+						if (val32)
+							break;
+
+						DBG_871X("%s: [HW_VAR_FIFO_CLEARN_UP] val=%x times:%d\n", __FUNCTION__, val32, trycnt);
+					} while (--trycnt);
+					if (trycnt == 0) {
+						DBG_8192C("[HW_VAR_FIFO_CLEARN_UP] Stop RX DMA failed......\n");
+					}
+
+					// RQPN Load 0
+					rtw_write16(padapter, REG_RQPN_NPQ, 0);
+					rtw_write32(padapter, REG_RQPN, 0x80000000);
+					rtw_mdelay_os(2);
+				}
+			}
+			break;
+
+		case HW_VAR_RESTORE_HW_SEQ:
+			/* restore Sequence No. */
+			rtw_write8(padapter, 0x4dc, padapter->xmitpriv.nqos_ssn);
+			break;
+
+#ifdef CONFIG_CONCURRENT_MODE
+		case HW_VAR_CHECK_TXBUF:
+			{
+				u32 i;
+				u8 RetryLimit = 0x01;
+				u32 reg_200, reg_204;
+
+				val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
+				rtw_write16(padapter, REG_RL, val16);
+
+				for (i=0; i<200; i++) // polling 200x10=2000 msec  
+				{
+					reg_200 = rtw_read32(padapter, 0x200);
+					reg_204 = rtw_read32(padapter, 0x204);
+					if (reg_200 != reg_204)
+					{
+						//DBG_871X("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i);
+						rtw_msleep_os(10);
+					}
+					else
+					{
+						DBG_871X("[HW_VAR_CHECK_TXBUF] no packet in tx packet buffer (%d)\n", i);
+						break;
+					}
+				}
+
+				if (reg_200 != reg_204)
+					DBG_871X("packets in tx buffer - 0x204=%x, 0x200=%x\n", reg_204, reg_200);
+				
+				RetryLimit = 0x30;
+				val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
+				rtw_write16(padapter, REG_RL, val16);
+			}
+			break;
+#endif // CONFIG_CONCURRENT_MODE
+
+		case HW_VAR_APFM_ON_MAC:
+			pHalData->bMacPwrCtrlOn = *val;
+#ifdef PLATFORM_LINUX
+			DBG_8192C("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn);
+#endif
+			break;
+
+		case HW_VAR_NAV_UPPER:
+			{
+				u32 usNavUpper = *((u32*)val);
+
+				if (usNavUpper > HAL_NAV_UPPER_UNIT_8703B * 0xFF)
+				{
+					RT_TRACE(_module_hal_init_c_, _drv_notice_, ("The setting value (0x%08X us) of NAV_UPPER is larger than (%d * 0xFF)!!!\n", usNavUpper, HAL_NAV_UPPER_UNIT_8703B));
+					break;
+				}
+
+				// The value of ((usNavUpper + HAL_NAV_UPPER_UNIT_8703B - 1) / HAL_NAV_UPPER_UNIT_8703B)
+				// is getting the upper integer.
+				usNavUpper = (usNavUpper + HAL_NAV_UPPER_UNIT_8703B - 1) / HAL_NAV_UPPER_UNIT_8703B;
+				rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
+			}
+			break;
+
+#ifndef CONFIG_C2H_PACKET_EN
+		case HW_VAR_C2H_HANDLE:
+			C2HCommandHandler(padapter);
+			break;
+#endif
+
+		case HW_VAR_BCN_VALID:
+#ifdef CONFIG_CONCURRENT_MODE
+			if (padapter->iface_type == IFACE_PORT1)
+			{
+				val8 = rtw_read8(padapter,  REG_DWBCN1_CTRL_8703B+2);
+				val8 |= BIT(0);
+				rtw_write8(padapter, REG_DWBCN1_CTRL_8703B+2, val8); 
+			}
+			else
+#endif // CONFIG_CONCURRENT_MODE
+			{
+				// BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw
+				val8 = rtw_read8(padapter, REG_TDECTRL+2);
+				val8 |= BIT(0);
+				rtw_write8(padapter, REG_TDECTRL+2, val8);
+			}
+			break;
+
+		case HW_VAR_DL_BCN_SEL:
+#ifdef CONFIG_CONCURRENT_MODE
+			if (padapter->iface_type == IFACE_PORT1)
+			{
+				// SW_BCN_SEL - Port1
+				val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8703B+2);
+				val8 |= BIT(4);
+				rtw_write8(padapter, REG_DWBCN1_CTRL_8703B+2, val8);
+			}
+			else
+#endif // CONFIG_CONCURRENT_MODE
+			{
+				// SW_BCN_SEL - Port0
+				val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8703B+2);
+				val8 &= ~BIT(4);
+				rtw_write8(padapter, REG_DWBCN1_CTRL_8703B+2, val8);	
+			}
+			break;
+
+		case HW_VAR_DO_IQK:
+			if (*val)
+				pHalData->bNeedIQK = _TRUE;
+			else
+				pHalData->bNeedIQK = _FALSE;
+			break;
+
+		case HW_VAR_DL_RSVD_PAGE:
+#ifdef CONFIG_BT_COEXIST
+			if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
+			{
+				rtl8703b_download_BTCoex_AP_mode_rsvd_page(padapter);
+			}
+			else
+#endif // CONFIG_BT_COEXIST
+			{
+				rtl8703b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
+			}
+			break;
+
+		case HW_VAR_MACID_SLEEP:
+		{
+			u32 reg_macid_sleep;
+			u8 bit_shift;
+			u8 id = *(u8*)val;
+
+			if (id < 32) {
+				reg_macid_sleep = REG_MACID_SLEEP;
+				bit_shift = id;
+			} else if (id < 64) {
+				reg_macid_sleep = REG_MACID_SLEEP_1;
+				bit_shift = id-32;
+			} else if (id < 96) {
+				reg_macid_sleep = REG_MACID_SLEEP_2;
+				bit_shift = id-64;
+			} else if (id < 128) {
+				reg_macid_sleep = REG_MACID_SLEEP_3;
+				bit_shift = id-96;
+			} else {
+				rtw_warn_on(1);
+				break;
+			}
+
+			val32 = rtw_read32(padapter, reg_macid_sleep);
+			DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org reg_0x%03x=0x%08X\n",
+				FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
+
+			if (val32 & BIT(bit_shift))
+				break;
+
+			val32 |= BIT(bit_shift);
+			rtw_write32(padapter, reg_macid_sleep, val32);
+		}
+			break;
+
+		case HW_VAR_MACID_WAKEUP:
+		{
+			u32 reg_macid_sleep;
+			u8 bit_shift;
+			u8 id = *(u8*)val;
+
+			if (id < 32) {
+				reg_macid_sleep = REG_MACID_SLEEP;
+				bit_shift = id;
+			} else if (id < 64) {
+				reg_macid_sleep = REG_MACID_SLEEP_1;
+				bit_shift = id-32;
+			} else if (id < 96) {
+				reg_macid_sleep = REG_MACID_SLEEP_2;
+				bit_shift = id-64;
+			} else if (id < 128) {
+				reg_macid_sleep = REG_MACID_SLEEP_3;
+				bit_shift = id-96;
+			} else {
+				rtw_warn_on(1);
+				break;
+			}
+
+			val32 = rtw_read32(padapter, reg_macid_sleep);
+			DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org reg_0x%03x=0x%08X\n",
+				FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
+
+			if (!(val32 & BIT(bit_shift)))
+				break;
+
+			val32 &= ~BIT(bit_shift);
+			rtw_write32(padapter, reg_macid_sleep, val32);
+		}
+			break;
+#ifdef CONFIG_GPIO_WAKEUP
+		case HW_SET_GPIO_WL_CTRL:
+		{
+			u8 enable = *val;
+			u8 value = rtw_read8(padapter, 0x4e);
+			if (enable && (value & BIT(6))) {
+				value &= ~BIT(6);
+				rtw_write8(padapter, 0x4e, value);
+			} else if (enable == _FALSE){
+				value |= BIT(6);
+				rtw_write8(padapter, 0x4e, value);
+			}
+			DBG_871X("%s: set WL control, 0x4E=0x%02X\n",
+					__func__, rtw_read8(padapter, 0x4e));
+		}
+			break;
+#endif
+		default:
+			SetHwReg(padapter, variable, val);
+			break;
+	}
+
+_func_exit_;
+}
+
+struct qinfo_8703b {
+	u32 head:8;
+	u32 pkt_num:7;
+	u32 tail:8;
+	u32 ac:2;
+	u32 macid:7;
+};
+
+struct bcn_qinfo_8703b {
+	u16 head:8;
+	u16 pkt_num:8;
+};
+
+void dump_qinfo_8703b(void *sel, struct qinfo_8703b *info, const char *tag)
+{
+	//if (info->pkt_num)
+	DBG_871X_SEL_NL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
+		, tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac
+	);
+}
+
+void dump_bcn_qinfo_8703b(void *sel, struct bcn_qinfo_8703b *info, const char *tag)
+{
+	//if (info->pkt_num)
+	DBG_871X_SEL_NL(sel, "%shead:0x%02x, pkt_num:%u\n"
+		, tag ? tag : "", info->head, info->pkt_num
+	);
+}
+
+void dump_mac_qinfo_8703b(void *sel, _adapter *adapter)
+{
+	u32 q0_info;
+	u32 q1_info;
+	u32 q2_info;
+	u32 q3_info;
+	u32 q4_info;
+	u32 q5_info;
+	u32 q6_info;
+	u32 q7_info;
+	u32 mg_q_info;
+	u32 hi_q_info;
+	u16 bcn_q_info;
+
+	q0_info = rtw_read32(adapter, REG_Q0_INFO);
+	q1_info = rtw_read32(adapter, REG_Q1_INFO);
+	q2_info = rtw_read32(adapter, REG_Q2_INFO);
+	q3_info = rtw_read32(adapter, REG_Q3_INFO);
+	q4_info = rtw_read32(adapter, REG_Q4_INFO);
+	q5_info = rtw_read32(adapter, REG_Q5_INFO);
+	q6_info = rtw_read32(adapter, REG_Q6_INFO);
+	q7_info = rtw_read32(adapter, REG_Q7_INFO);
+	mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
+	hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
+	bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
+
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q0_info, "Q0 ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q1_info, "Q1 ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q2_info, "Q2 ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q3_info, "Q3 ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q4_info, "Q4 ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q5_info, "Q5 ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q6_info, "Q6 ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q7_info, "Q7 ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&mg_q_info, "MG ");
+	dump_qinfo_8703b(sel, (struct qinfo_8703b *)&hi_q_info, "HI ");
+	dump_bcn_qinfo_8703b(sel, (struct bcn_qinfo_8703b *)&bcn_q_info, "BCN ");
+}
+
+void GetHwReg8703B(PADAPTER padapter, u8 variable, u8 *val)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	u8 val8;
+	u16 val16;
+	u32 val32;
+
+
+	switch (variable)
+	{
+		case HW_VAR_TXPAUSE:
+			*val = rtw_read8(padapter, REG_TXPAUSE);
+			break;
+
+		case HW_VAR_BCN_VALID:
+#ifdef CONFIG_CONCURRENT_MODE
+			if (padapter->iface_type == IFACE_PORT1)
+			{
+				val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8703B+2);
+				*val = (BIT(0) & val8) ? _TRUE:_FALSE;
+			}
+			else
+#endif
+			{
+				// BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2
+				val8 = rtw_read8(padapter, REG_TDECTRL+2);
+				*val = (BIT(0) & val8) ? _TRUE:_FALSE;
+			}
+			break;
+
+		case HW_VAR_FWLPS_RF_ON:
+			{
+				// When we halt NIC, we should check if FW LPS is leave.
+				u32 valRCR;
+
+				if (rtw_is_surprise_removed(padapter) ||
+					(adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off))
+				{
+					// If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave,
+					// because Fw is unload.
+					*val = _TRUE;
+				}
+				else
+				{
+					valRCR = rtw_read32(padapter, REG_RCR);
+					valRCR &= 0x00070000;
+					if(valRCR)
+						*val = _FALSE;
+					else
+						*val = _TRUE;
+				}
+			}
+			break;
+
+#ifdef CONFIG_ANTENNA_DIVERSITY
+		case HW_VAR_CURRENT_ANTENNA:
+			*val = pHalData->CurAntenna;
+			break;
+#endif
+
+		case HW_VAR_EFUSE_USAGE:
+			*val = pHalData->EfuseUsedPercentage;
+			break;
+
+		case HW_VAR_EFUSE_BYTES:
+			*((u16*)val) = pHalData->EfuseUsedBytes;
+			break;
+
+		case HW_VAR_EFUSE_BT_USAGE:
+#ifdef HAL_EFUSE_MEMORY
+			*val = pHalData->EfuseHal.BTEfuseUsedPercentage;
+#endif
+			break;
+
+		case HW_VAR_EFUSE_BT_BYTES:
+#ifdef HAL_EFUSE_MEMORY
+			*((u16*)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
+#else
+			*((u16*)val) = BTEfuseUsedBytes;
+#endif
+			break;
+
+		case HW_VAR_APFM_ON_MAC:
+			*val = pHalData->bMacPwrCtrlOn;
+			break;
+		case HW_VAR_CHK_HI_QUEUE_EMPTY:
+			val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
+			*val = (val16 & BIT(10)) ? _TRUE:_FALSE;
+			break;
+#ifdef CONFIG_WOWLAN
+		case HW_VAR_RPWM_TOG:
+			*val = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1) & BIT7;
+			break;
+		case HW_VAR_WAKEUP_REASON:
+			*val = rtw_read8(padapter, REG_WOWLAN_WAKE_REASON);
+			if(*val == 0xEA)
+				*val = 0;
+			break;
+		case HW_VAR_SYS_CLKR:
+			*val = rtw_read8(padapter, REG_SYS_CLKR);
+			break;
+#endif
+		case HW_VAR_DUMP_MAC_QUEUE_INFO:
+			dump_mac_qinfo_8703b(val, padapter);
+			break;
+		default:
+			GetHwReg(padapter, variable, val);
+			break;
+	}
+}
+
+/*
+ *	Description:
+ *		Change default setting of specified variable.
+ */
+u8 SetHalDefVar8703B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
+{
+	PHAL_DATA_TYPE pHalData;
+	u8 bResult;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	bResult = _SUCCESS;
+
+	switch (variable)
+	{
+		default:
+			bResult = SetHalDefVar(padapter, variable, pval);
+			break;
+	}
+
+	return bResult;
+}
+
+#ifdef CONFIG_C2H_PACKET_EN
+void SetHwRegWithBuf8703B(PADAPTER padapter, u8 variable, u8 *pbuf, int len)
+{
+	PHAL_DATA_TYPE pHalData;
+
+_func_enter_;
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	switch (variable) {
+	case HW_VAR_C2H_HANDLE:
+		C2HPacketHandler_8703B(padapter, pbuf, len);
+		break;
+
+	default:
+		break;
+	}
+_func_exit_;
+}
+#endif // CONFIG_C2H_PACKET_EN
+
+/*
+ *	Description: 
+ *		Query setting of specified variable.
+ */
+u8 GetHalDefVar8703B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
+{
+	PHAL_DATA_TYPE pHalData;
+	u8 bResult;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	bResult = _SUCCESS;
+
+	switch (variable)
+	{
+		case HAL_DEF_MAX_RECVBUF_SZ:
+			*((u32*)pval) = MAX_RECVBUF_SZ;
+			break;
+
+		case HAL_DEF_RX_PACKET_OFFSET:
+			*((u32*)pval) = RXDESC_SIZE + DRVINFO_SZ*8;
+			break;
+
+		case HW_VAR_MAX_RX_AMPDU_FACTOR:
+			// Stanley@BB.SD3 suggests 16K can get stable performance
+			// The experiment was done on SDIO interface
+			// coding by Lucas@20130730
+			*(HT_CAP_AMPDU_FACTOR*)pval = MAX_AMPDU_FACTOR_16K;
+			break;
+		case HW_VAR_BEST_AMPDU_DENSITY:
+			*((u32 *)pval) = AMPDU_DENSITY_VALUE_7;
+			break;
+		case HAL_DEF_TX_LDPC:
+		case HAL_DEF_RX_LDPC:
+			*((u8 *)pval) = _FALSE;
+			break;
+		case HAL_DEF_TX_STBC:
+			*((u8 *)pval) = 0;
+			break;
+		case HAL_DEF_RX_STBC:
+			*((u8 *)pval) = 1;
+			break;
+		case HAL_DEF_EXPLICIT_BEAMFORMER:
+		case HAL_DEF_EXPLICIT_BEAMFORMEE:
+			*((u8 *)pval) = _FALSE;
+			break;
+
+		case HW_DEF_RA_INFO_DUMP:
+			{
+				u8 mac_id = *(u8*)pval;
+				u32 cmd;
+				u32 ra_info1, ra_info2;
+				u32 rate_mask1, rate_mask2;
+				u8 curr_tx_rate,curr_tx_sgi,hight_rate,lowest_rate;			
+				
+				DBG_8192C("============ RA status check  Mac_id:%d ===================\n", mac_id);
+
+				cmd = 0x40000100 | mac_id;
+				rtw_write32(padapter, REG_HMEBOX_DBG_2_8703B, cmd);
+				rtw_msleep_os(10);
+				ra_info1 = rtw_read32(padapter, 0x2F0);
+				curr_tx_rate = ra_info1&0x7F;
+				curr_tx_sgi = (ra_info1>>7)&0x01;
+				DBG_8192C("[ ra_info1:0x%08x ] =>cur_tx_rate= %s,cur_sgi:%d, PWRSTS = 0x%02x  \n",
+					ra_info1,						
+					HDATA_RATE(curr_tx_rate),
+					curr_tx_sgi,
+					(ra_info1>>8)  & 0x07);
+
+				cmd = 0x40000400 | mac_id;
+				rtw_write32(padapter, REG_HMEBOX_DBG_2_8703B,cmd);
+				rtw_msleep_os(10);
+				ra_info1 = rtw_read32(padapter, 0x2F0);
+				ra_info2 = rtw_read32(padapter, 0x2F4);
+				rate_mask1 = rtw_read32(padapter, 0x2F8);
+				rate_mask2 = rtw_read32(padapter, 0x2FC);
+				hight_rate = ra_info2&0xFF;
+				lowest_rate = (ra_info2>>8)  & 0xFF;
+					
+				DBG_8192C("[ ra_info1:0x%08x ] =>RSSI=%d, BW_setting=0x%02x, DISRA=0x%02x, VHT_EN=0x%02x\n",
+					ra_info1,
+					ra_info1&0xFF,
+					(ra_info1>>8)  & 0xFF,
+					(ra_info1>>16) & 0xFF,
+					(ra_info1>>24) & 0xFF);
+					
+				DBG_8192C("[ ra_info2:0x%08x ] =>hight_rate=%s, lowest_rate=%s, SGI=0x%02x, RateID=%d\n",
+					ra_info2,
+					HDATA_RATE(hight_rate),
+					HDATA_RATE(lowest_rate),
+					(ra_info2>>16) & 0xFF,
+					(ra_info2>>24) & 0xFF);
+
+				DBG_8192C("rate_mask2=0x%08x, rate_mask1=0x%08x\n", rate_mask2, rate_mask1);
+				
+			}
+			break;
+
+		case HAL_DEF_TX_PAGE_BOUNDARY:
+			if (!padapter->registrypriv.wifi_spec)
+			{
+				*(u8*)pval = TX_PAGE_BOUNDARY_8703B;
+			}
+			else
+			{
+				*(u8*)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8703B;
+			}
+			break;
+
+		case HAL_DEF_MACID_SLEEP:
+			*(u8*)pval = _TRUE; // support macid sleep
+			break;
+		case HAL_DEF_TX_PAGE_SIZE:
+			 *(( u32*)pval) = PAGE_SIZE_128;
+			break;
+		case HAL_DEF_RX_DMA_SZ_WOW:
+			*(u32 *)pval = RX_DMA_SIZE_8703B - RESV_FMWF;
+			break;
+		case HAL_DEF_RX_DMA_SZ:
+			*(u32 *)pval = RX_DMA_BOUNDARY_8703B + 1;
+			break;
+		case HAL_DEF_RX_PAGE_SIZE:
+			*((u32 *)pval) = 8;
+			break;
+		default:
+			bResult = GetHalDefVar(padapter, variable, pval);
+			break;
+	}
+
+	return bResult;
+}
+
+#ifdef CONFIG_WOWLAN
+void Hal_DetectWoWMode(PADAPTER pAdapter)
+{
+	adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;
+	DBG_871X("%s\n", __func__);
+}
+#endif //CONFIG_WOWLAN
+
+void rtl8703b_start_thread(_adapter *padapter)
+{
+#if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
+#ifndef CONFIG_SDIO_TX_TASKLET
+	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
+
+	xmitpriv->SdioXmitThread = kthread_run(rtl8703bs_xmit_thread, padapter, "RTWHALXT");
+	if (IS_ERR(xmitpriv->SdioXmitThread))
+	{
+		RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: start rtl8703bs_xmit_thread FAIL!!\n", __FUNCTION__));
+	}
+#endif
+#endif
+}
+
+void rtl8703b_stop_thread(_adapter *padapter)
+{
+#if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
+#ifndef CONFIG_SDIO_TX_TASKLET
+	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
+
+	// stop xmit_buf_thread
+	if (xmitpriv->SdioXmitThread ) {
+		_rtw_up_sema(&xmitpriv->SdioXmitSema);
+		_rtw_down_sema(&xmitpriv->SdioXmitTerminateSema);
+		xmitpriv->SdioXmitThread = 0;
+	}
+#endif
+#endif
+}
+
+#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
+extern void check_bt_status_work(void *data);
+void rtl8703bs_init_checkbthang_workqueue(_adapter * adapter)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+	adapter->priv_checkbt_wq = alloc_workqueue("sdio_wq", 0, 0);
+#else
+	adapter->priv_checkbt_wq = create_workqueue("sdio_wq");
+#endif
+	INIT_DELAYED_WORK(&adapter->checkbt_work, (void*)check_bt_status_work);
+}
+
+void rtl8703bs_free_checkbthang_workqueue(_adapter * adapter)
+{
+	if (adapter->priv_checkbt_wq) {
+		cancel_delayed_work_sync(&adapter->checkbt_work);
+		flush_workqueue(adapter->priv_checkbt_wq);
+		destroy_workqueue(adapter->priv_checkbt_wq);
+		adapter->priv_checkbt_wq = NULL;
+	} 
+}
+
+void rtl8703bs_cancle_checkbthang_workqueue(_adapter * adapter)
+{
+	if (adapter->priv_checkbt_wq) {
+		cancel_delayed_work_sync(&adapter->checkbt_work);
+	}
+}
+
+void rtl8703bs_hal_check_bt_hang(_adapter * adapter)
+{
+	if (adapter->priv_checkbt_wq)
+		queue_delayed_work(adapter->priv_checkbt_wq, &(adapter->checkbt_work), 0);
+}
+#endif
+
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_phycfg.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_phycfg.c
new file mode 100644
index 000000000..7a41d3068
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_phycfg.c
@@ -0,0 +1,1559 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#define _RTL8703B_PHYCFG_C_
+
+#include <rtl8703b_hal.h>
+
+
+/*---------------------------Define Local Constant---------------------------*/
+/* Channel switch:The size of command tables for switch channel*/
+#define MAX_PRECMD_CNT 16
+#define MAX_RFDEPENDCMD_CNT 16
+#define MAX_POSTCMD_CNT 16
+
+#define MAX_DOZE_WAITING_TIMES_9x 64
+
+/*---------------------------Define Local Constant---------------------------*/
+
+
+/*------------------------Define global variable-----------------------------*/
+
+/*------------------------Define local variable------------------------------*/
+
+
+/*--------------------Define export function prototype-----------------------*/
+// Please refer to header file
+/*--------------------Define export function prototype-----------------------*/
+
+/*----------------------------Function Body----------------------------------*/
+//
+// 1. BB register R/W API
+//
+
+/**
+* Function:	phy_CalculateBitShift
+*
+* OverView:	Get shifted position of the BitMask
+*
+* Input:
+*			u4Byte		BitMask,
+*
+* Output:	none
+* Return:		u4Byte		Return the shift bit bit position of the mask
+*/
+static	u32
+phy_CalculateBitShift(
+	u32 BitMask
+	)
+{
+	u32 i;
+
+	for(i=0; i<=31; i++)
+	{
+		if ( ((BitMask>>i) &  0x1 ) == 1)
+			break;
+	}
+
+	return (i);
+}
+
+
+/**
+* Function:	PHY_QueryBBReg
+*
+* OverView:	Read "sepcific bits" from BB register
+*
+* Input:
+*			PADAPTER		Adapter,
+*			u4Byte			RegAddr,		//The target address to be readback
+*			u4Byte			BitMask		//The target bit position in the target address
+*										//to be readback
+* Output:	None
+* Return:		u4Byte			Data			//The readback register value
+* Note:		This function is equal to "GetRegSetting" in PHY programming guide
+*/
+u32
+PHY_QueryBBReg_8703B(
+	IN	PADAPTER	Adapter,
+	IN	u32		RegAddr,
+	IN	u32		BitMask
+	)
+{
+  	u32	ReturnValue = 0, OriginalValue, BitShift;
+	u16	BBWaitCounter = 0;
+
+#if (DISABLE_BB_RF == 1)
+	return 0;
+#endif
+
+	//RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_QueryBBReg(): RegAddr(%#lx), BitMask(%#lx)\n", RegAddr, BitMask));
+
+	OriginalValue = rtw_read32(Adapter, RegAddr);
+	BitShift = phy_CalculateBitShift(BitMask);
+	ReturnValue = (OriginalValue & BitMask) >> BitShift;
+
+	return (ReturnValue);
+
+}
+
+
+/**
+* Function:	PHY_SetBBReg
+*
+* OverView:	Write "Specific bits" to BB register (page 8~)
+*
+* Input:
+*			PADAPTER		Adapter,
+*			u4Byte			RegAddr,		//The target address to be modified
+*			u4Byte			BitMask		//The target bit position in the target address
+*										//to be modified
+*			u4Byte			Data			//The new register value in the target bit position
+*										//of the target address
+*
+* Output:	None
+* Return:		None
+* Note:		This function is equal to "PutRegSetting" in PHY programming guide
+*/
+
+VOID
+PHY_SetBBReg_8703B(
+	IN	PADAPTER	Adapter,
+	IN	u32		RegAddr,
+	IN	u32		BitMask,
+	IN	u32		Data
+	)
+{
+	HAL_DATA_TYPE	*pHalData		= GET_HAL_DATA(Adapter);
+	//u16			BBWaitCounter	= 0;
+	u32			OriginalValue, BitShift;
+
+#if (DISABLE_BB_RF == 1)
+	return;
+#endif
+
+	//RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data));
+
+	if(BitMask!= bMaskDWord){//if not "double word" write
+		OriginalValue = rtw_read32(Adapter, RegAddr);
+		BitShift = phy_CalculateBitShift(BitMask);
+		Data = ((OriginalValue & (~BitMask)) | ((Data << BitShift) & BitMask));
+	}
+
+	rtw_write32(Adapter, RegAddr, Data);
+
+}
+
+
+//
+// 2. RF register R/W API
+//
+
+/*-----------------------------------------------------------------------------
+ * Function:	phy_FwRFSerialRead()
+ *
+ * Overview:	We support firmware to execute RF-R/W.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	01/21/2008	MHC		Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+static	u32
+phy_FwRFSerialRead(
+	IN	PADAPTER			Adapter,
+	IN	RF_PATH			eRFPath,
+	IN	u32				Offset	)
+{
+	u32		retValue = 0;
+	//RT_ASSERT(FALSE,("deprecate!\n"));
+	return	(retValue);
+
+}	/* phy_FwRFSerialRead */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	phy_FwRFSerialWrite()
+ *
+ * Overview:	We support firmware to execute RF-R/W.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	01/21/2008	MHC		Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+static	VOID
+phy_FwRFSerialWrite(
+	IN	PADAPTER			Adapter,
+	IN	RF_PATH			eRFPath,
+	IN	u32				Offset,
+	IN	u32				Data	)
+{
+	//RT_ASSERT(FALSE,("deprecate!\n"));
+}
+
+static	u32
+phy_RFSerialRead_8703B(
+	IN	PADAPTER			Adapter,
+	IN	RF_PATH			eRFPath,
+	IN	u32				Offset
+	)
+{
+	u32						retValue = 0;
+	HAL_DATA_TYPE				*pHalData = GET_HAL_DATA(Adapter);
+	BB_REGISTER_DEFINITION_T	*pPhyReg = &pHalData->PHYRegDef[eRFPath];
+	u32						NewOffset;
+	u32 						tmplong,tmplong2;
+	u8					RfPiEnable=0;
+	u4Byte						MaskforPhySet=0;
+	int i = 0;
+
+	_enter_critical_mutex(&(adapter_to_dvobj(Adapter)->rf_read_reg_mutex) , NULL);
+	//
+	// Make sure RF register offset is correct
+	//
+	Offset &= 0xff;
+
+	NewOffset = Offset;
+
+	if(eRFPath == RF_PATH_A)
+	{
+		tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);;
+		tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge;	//T65 RF
+		PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge));	
+	}
+	else
+	{
+		tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter2|MaskforPhySet, bMaskDWord);
+		tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge;	//T65 RF
+		PHY_SetBBReg(Adapter, rFPGA0_XB_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge));	
+	}
+
+	tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);
+	PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2 & (~bLSSIReadEdge));			
+	PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2 | bLSSIReadEdge);		
+	
+	rtw_udelay_os(10);
+
+	for(i=0;i<2;i++)
+		rtw_udelay_os(MAX_STALL_TIME);	
+	rtw_udelay_os(10);
+
+	if(eRFPath == RF_PATH_A)
+		RfPiEnable = (u1Byte)PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1|MaskforPhySet, BIT8);
+	else if(eRFPath == RF_PATH_B)
+		RfPiEnable = (u1Byte)PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter1|MaskforPhySet, BIT8);
+	
+	if(RfPiEnable)
+	{	// Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF
+		retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi|MaskforPhySet, bLSSIReadBackData);
+	
+		//RT_DISP(FINIT, INIT_RF, ("Readback from RF-PI : 0x%x\n", retValue));
+	}
+	else
+	{	//Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF
+		retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack|MaskforPhySet, bLSSIReadBackData);
+		
+		//RT_DISP(FINIT, INIT_RF,("Readback from RF-SI : 0x%x\n", retValue));
+	}
+	_exit_critical_mutex(&(adapter_to_dvobj(Adapter)->rf_read_reg_mutex) , NULL);
+	return retValue;
+
+}
+
+/**
+* Function:	phy_RFSerialWrite_8703B
+*
+* OverView:	Write data to RF register (page 8~)
+*
+* Input:
+*			PADAPTER		Adapter,
+*			RF_PATH			eRFPath,	//Radio path of A/B/C/D
+*			u4Byte			Offset,		//The target address to be read
+*			u4Byte			Data			//The new register Data in the target bit position
+*										//of the target to be read
+*
+* Output:	None
+* Return:		None
+* Note:		Threre are three types of serial operations:
+*			1. Software serial write
+*			2. Hardware LSSI-Low Speed Serial Interface
+*			3. Hardware HSSI-High speed
+*			serial write. Driver need to implement (1) and (2).
+*			This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
+ *
+ * Note: 		  For RF8256 only
+ *			 The total count of RTL8256(Zebra4) register is around 36 bit it only employs
+ *			 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
+ *			 to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
+ *			 programming guide" for more details.
+ *			 Thus, we define a sub-finction for RTL8526 register address conversion
+ *		       ===========================================================
+ *			 Register Mode		RegCTL[1]		RegCTL[0]		Note
+ *								(Reg00[12])		(Reg00[10])
+ *		       ===========================================================
+ *			 Reg_Mode0				0				x			Reg 0 ~15(0x0 ~ 0xf)
+ *		       ------------------------------------------------------------------
+ *			 Reg_Mode1				1				0			Reg 16 ~30(0x1 ~ 0xf)
+ *		       ------------------------------------------------------------------
+ *			 Reg_Mode2				1				1			Reg 31 ~ 45(0x1 ~ 0xf)
+ *		       ------------------------------------------------------------------
+ *
+ *	2008/09/02	MH	Add 92S RF definition
+ *
+ *
+ *
+*/
+static	VOID
+phy_RFSerialWrite_8703B(
+	IN	PADAPTER			Adapter,
+	IN	RF_PATH			eRFPath,
+	IN	u32				Offset,
+	IN	u32				Data
+	)
+{
+	u32						DataAndAddr = 0;
+	HAL_DATA_TYPE				*pHalData = GET_HAL_DATA(Adapter);
+	BB_REGISTER_DEFINITION_T	*pPhyReg = &pHalData->PHYRegDef[eRFPath];
+	u32						NewOffset;
+
+	Offset &= 0xff;
+
+	//
+	// Shadow Update
+	//
+	//PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data);
+
+	//
+	// Switch page for 8256 RF IC
+	//
+	NewOffset = Offset;
+
+	//
+	// Put write addr in [5:0]  and write data in [31:16]
+	//
+	//DataAndAddr = (Data<<16) | (NewOffset&0x3f);
+	DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff;	// T65 RF
+
+	//
+	// Write Operation
+	//
+	PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
+	//RTPRINT(FPHY, PHY_RFW, ("RFW-%d Addr[0x%lx]=0x%lx\n", eRFPath, pPhyReg->rf3wireOffset, DataAndAddr));
+
+}
+
+
+/**
+* Function:	PHY_QueryRFReg
+*
+* OverView:	Query "Specific bits" to RF register (page 8~)
+*
+* Input:
+*			PADAPTER		Adapter,
+*			RF_PATH			eRFPath,	//Radio path of A/B/C/D
+*			u4Byte			RegAddr,		//The target address to be read
+*			u4Byte			BitMask		//The target bit position in the target address
+*										//to be read
+*
+* Output:	None
+* Return:		u4Byte			Readback value
+* Note:		This function is equal to "GetRFRegSetting" in PHY programming guide
+*/
+u32
+PHY_QueryRFReg_8703B(
+	IN	PADAPTER			Adapter,
+	IN	u8			eRFPath,
+	IN	u32				RegAddr,
+	IN	u32				BitMask
+	)
+{
+	u32 Original_Value, Readback_Value, BitShift;
+
+#if (DISABLE_BB_RF == 1)
+	return 0;
+#endif
+
+	Original_Value = phy_RFSerialRead_8703B(Adapter, eRFPath, RegAddr);
+
+	BitShift =  phy_CalculateBitShift(BitMask);
+	Readback_Value = (Original_Value & BitMask) >> BitShift;
+
+	return (Readback_Value);
+}
+
+/**
+* Function:	PHY_SetRFReg
+*
+* OverView:	Write "Specific bits" to RF register (page 8~)
+*
+* Input:
+*			PADAPTER		Adapter,
+*			RF_PATH			eRFPath,	//Radio path of A/B/C/D
+*			u4Byte			RegAddr,		//The target address to be modified
+*			u4Byte			BitMask		//The target bit position in the target address
+*										//to be modified
+*			u4Byte			Data			//The new register Data in the target bit position
+*										//of the target address
+*
+* Output:	None
+* Return:		None
+* Note:		This function is equal to "PutRFRegSetting" in PHY programming guide
+*/
+VOID
+PHY_SetRFReg_8703B(
+	IN	PADAPTER			Adapter,
+	IN	u8				eRFPath,
+	IN	u32				RegAddr,
+	IN	u32				BitMask,
+	IN	u32				Data
+	)
+{
+	u32		Original_Value, BitShift;
+
+#if (DISABLE_BB_RF == 1)
+	return;
+#endif
+
+	// RF data is 12 bits only
+	if (BitMask != bRFRegOffsetMask)
+	{
+		Original_Value = phy_RFSerialRead_8703B(Adapter, eRFPath, RegAddr);
+		BitShift =  phy_CalculateBitShift(BitMask);
+		Data = ((Original_Value & (~BitMask)) | (Data<< BitShift));
+	}
+
+	phy_RFSerialWrite_8703B(Adapter, eRFPath, RegAddr, Data);
+}
+
+
+//
+// 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt.
+//
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    PHY_MACConfig8192C
+ *
+ * Overview:	Condig MAC by header file or parameter file.
+ *
+ * Input:       NONE
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  08/12/2008	MHC		Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+s32 PHY_MACConfig8703B(PADAPTER Adapter)
+{
+	int		rtStatus = _SUCCESS;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	s8			*pszMACRegFile;
+	s8			sz8703MACRegFile[] = RTL8703B_PHY_MACREG;
+
+
+	pszMACRegFile = sz8703MACRegFile;
+
+	//
+	// Config MAC
+	//
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+	rtStatus = phy_ConfigMACWithParaFile(Adapter, pszMACRegFile);
+	if (rtStatus == _FAIL)
+#endif
+	{
+#ifdef CONFIG_EMBEDDED_FWIMG
+		ODM_ConfigMACWithHeaderFile(&pHalData->odmpriv);
+		rtStatus = _SUCCESS;
+#endif//CONFIG_EMBEDDED_FWIMG
+	}
+
+	return rtStatus;
+}
+
+/**
+* Function:	phy_InitBBRFRegisterDefinition
+*
+* OverView:	Initialize Register definition offset for Radio Path A/B/C/D
+*
+* Input:
+*			PADAPTER		Adapter,
+*
+* Output:	None
+* Return:		None
+* Note:		The initialization value is constant and it should never be changes
+*/
+static	VOID
+phy_InitBBRFRegisterDefinition(
+	IN	PADAPTER		Adapter
+)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);	
+
+	// RF Interface Sowrtware Control
+	pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870
+	pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872)
+
+	// RF Interface Output (and Enable)
+	pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860
+	pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864
+
+	// RF Interface (Output and)  Enable
+	pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862)
+	pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866)
+
+	pHalData->PHYRegDef[ODM_RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter
+	pHalData->PHYRegDef[ODM_RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
+
+	pHalData->PHYRegDef[ODM_RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;  //wire control parameter2
+	pHalData->PHYRegDef[ODM_RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;  //wire control parameter2
+
+        // Tranceiver Readback LSSI/HSPI mode 
+	pHalData->PHYRegDef[ODM_RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
+	pHalData->PHYRegDef[ODM_RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
+	pHalData->PHYRegDef[ODM_RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
+	pHalData->PHYRegDef[ODM_RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback;
+
+}
+
+#if (MP_DRIVER == 1)
+
+/*-----------------------------------------------------------------------------
+ * Function:	phy_ConfigBBWithMpHeaderFile
+ *
+ * Overview:	Config PHY_REG_MP array
+ *
+ * Input:       NONE
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ * When			Who		Remark
+ * 02/04/2010	chiyokolin		Modify to new files.
+ *---------------------------------------------------------------------------*/
+static int
+phy_ConfigBBWithMpHeaderFile(
+	IN	PADAPTER		Adapter,
+	IN	u1Byte 			ConfigType)
+{
+	int i;
+	u32*	Rtl8703BPHY_REGArray_Table_MP;
+	u16	PHY_REGArrayMPLen;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+
+#if 0
+	PHY_REGArrayMPLen = Rtl8703B_PHY_REG_Array_MPLength;
+	Rtl8703BPHY_REGArray_Table_MP = (u32*)Rtl8703B_PHY_REG_Array_MP;
+
+	if(ConfigType == BaseBand_Config_PHY_REG)
+	{
+		for(i=0;i<PHY_REGArrayMPLen;i=i+2)
+		{
+			if (Rtl8703BPHY_REGArray_Table_MP[i] == 0xfe) {
+				#ifdef CONFIG_LONG_DELAY_ISSUE
+				rtw_msleep_os(50);
+				#else
+				rtw_mdelay_os(50);
+				#endif
+			}
+			else if (Rtl8703BPHY_REGArray_Table_MP[i] == 0xfd)
+				rtw_mdelay_os(5);
+			else if (Rtl8703BPHY_REGArray_Table_MP[i] == 0xfc)
+				rtw_mdelay_os(1);
+			else if (Rtl8703BPHY_REGArray_Table_MP[i] == 0xfb) {
+				#ifdef CONFIG_LONG_DELAY_ISSUE
+				rtw_msleep_os(50);
+				#else
+				rtw_mdelay_os(50);
+				#endif
+			}
+			else if (Rtl8703BPHY_REGArray_Table_MP[i] == 0xfa)
+				rtw_mdelay_os(5);
+			else if (Rtl8703BPHY_REGArray_Table_MP[i] == 0xf9)
+				rtw_mdelay_os(1);
+			PHY_SetBBReg(Adapter, Rtl8703BPHY_REGArray_Table_MP[i], bMaskDWord, Rtl8703BPHY_REGArray_Table_MP[i+1]);
+
+			// Add 1us delay between BB/RF register setting.
+			rtw_mdelay_os(1);
+
+//			RT_TRACE(COMP_INIT, DBG_TRACE, ("The Rtl8192CPHY_REGArray_Table_MP[%d] is %lx Rtl8192CPHY_REGArray_Table_MP[%d] is %lx \n", i, i+1, Rtl8192CPHY_REGArray_Table_MP[i], Rtl8192CPHY_REGArray_Table_MP[i+1]));
+		}
+	}
+	else
+	{
+//		RT_TRACE(COMP_SEND, DBG_LOUD, ("phy_ConfigBBWithMpHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n"));
+	}
+#endif
+
+	return _SUCCESS;
+}	/* phy_ConfigBBWithMpHeaderFile */
+
+#endif	// #if (MP_DRIVER == 1)
+
+
+static	int
+phy_BB8703b_Config_ParaFile(
+	IN	PADAPTER	Adapter
+	)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+	int			rtStatus = _SUCCESS;
+	u8	sz8703BBRegFile[] = RTL8703B_PHY_REG;
+	u8	sz8703AGCTableFile[] = RTL8703B_AGC_TAB;
+	u8	sz8703BBRegMpFile[] = RTL8703B_PHY_REG_MP;
+	u8	*pszBBRegFile = NULL, *pszAGCTableFile = NULL, *pszBBRegMpFile = NULL;
+
+	pszBBRegFile = sz8703BBRegFile;
+	pszAGCTableFile = sz8703AGCTableFile;
+	pszBBRegMpFile = sz8703BBRegMpFile;
+
+	//
+	// 1. Read PHY_REG.TXT BB INIT!!
+	//
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+	if (phy_ConfigBBWithParaFile(Adapter, pszBBRegFile, CONFIG_BB_PHY_REG) == _FAIL)
+#endif
+	{
+#ifdef CONFIG_EMBEDDED_FWIMG
+		if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG))
+			rtStatus = _FAIL;
+#endif
+	}
+
+	if(rtStatus != _SUCCESS){
+		DBG_8192C("%s():Write BB Reg Fail!!", __func__);
+		goto phy_BB8190_Config_ParaFile_Fail;
+	}
+
+#if MP_DRIVER == 1
+	if (Adapter->registrypriv.mp_mode == 1)
+	{
+		//
+		// 1.1 Read PHY_REG_MP.TXT BB INIT!!
+		//
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+		if (phy_ConfigBBWithMpParaFile(Adapter, pszBBRegMpFile) == _FAIL)
+#endif
+		{
+#ifdef CONFIG_EMBEDDED_FWIMG
+			if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG_MP))
+				rtStatus = _FAIL;
+#endif
+		}
+
+		if(rtStatus != _SUCCESS){
+			DBG_8192C("%s():Write BB Reg MP Fail!!", __func__);
+			goto phy_BB8190_Config_ParaFile_Fail;
+		}
+	}
+#endif	// #if (MP_DRIVER == 1)
+
+	//
+	// 2. Read BB AGC table Initialization
+	//
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+	if (phy_ConfigBBWithParaFile(Adapter, pszAGCTableFile, CONFIG_BB_AGC_TAB) == _FAIL)
+#endif
+	{
+#ifdef CONFIG_EMBEDDED_FWIMG
+		if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB))
+			rtStatus = _FAIL;
+#endif
+	}
+
+	if(rtStatus != _SUCCESS){
+		DBG_8192C("%s():AGC Table Fail\n", __func__);
+		goto phy_BB8190_Config_ParaFile_Fail;
+	}
+
+phy_BB8190_Config_ParaFile_Fail:
+
+	return rtStatus;
+}
+
+
+int
+PHY_BBConfig8703B(
+	IN	PADAPTER	Adapter
+	)
+{
+	int	rtStatus = _SUCCESS;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	u32	RegVal;
+	u8	TmpU1B=0;
+	u8	value8;
+
+	phy_InitBBRFRegisterDefinition(Adapter);
+
+	// Enable BB and RF
+	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+	rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1));
+
+	rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB);
+
+	rtw_usleep_os(10);
+
+	PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1, 0xfffff,0x780); 
+
+#if 0
+	// 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF.
+	rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x83);
+	rtw_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xdb);
+#endif
+
+	rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_PPLL|FEN_PCIEA|FEN_DIO_PCIE|FEN_BB_GLB_RSTn|FEN_BBRSTB);
+
+	rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, 0x80);
+
+	//
+	// Config BB and AGC
+	//
+	rtStatus = phy_BB8703b_Config_ParaFile(Adapter);
+
+	hal_set_crystal_cap(Adapter, pHalData->CrystalCap);
+
+	return rtStatus;
+}
+
+void phy_LCK_8703B(
+	IN	PADAPTER	Adapter
+	)
+{
+	PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0);
+	PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, 0x8C01);	
+	rtw_mdelay_os(200);
+	PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0);	
+}
+
+#if 0
+// Block & Path enable
+#define		rOFDMCCKEN_Jaguar 		0x808 // OFDM/CCK block enable
+#define		bOFDMEN_Jaguar			0x20000000
+#define		bCCKEN_Jaguar			0x10000000
+#define		rRxPath_Jaguar			0x808	// Rx antenna
+#define		bRxPath_Jaguar			0xff
+#define		rTxPath_Jaguar			0x80c	// Tx antenna
+#define		bTxPath_Jaguar			0x0fffffff
+#define		rCCK_RX_Jaguar			0xa04	// for cck rx path selection
+#define		bCCK_RX_Jaguar			0x0c000000 
+#define		rVhtlen_Use_Lsig_Jaguar	0x8c3	// Use LSIG for VHT length
+VOID
+PHY_BB8703B_Config_1T(
+	IN PADAPTER Adapter
+	)
+{
+	// BB OFDM RX Path_A
+	PHY_SetBBReg(Adapter, rRxPath_Jaguar, bRxPath_Jaguar, 0x11);
+	// BB OFDM TX Path_A
+	PHY_SetBBReg(Adapter, rTxPath_Jaguar, bMaskLWord, 0x1111);
+	// BB CCK R/Rx Path_A
+	PHY_SetBBReg(Adapter, rCCK_RX_Jaguar, bCCK_RX_Jaguar, 0x0);
+	// MCS support
+	PHY_SetBBReg(Adapter, 0x8bc, 0xc0000060, 0x4);
+	// RF Path_B HSSI OFF
+	PHY_SetBBReg(Adapter, 0xe00, 0xf, 0x4);	
+	// RF Path_B Power Down
+	PHY_SetBBReg(Adapter, 0xe90, bMaskDWord, 0);
+	// ADDA Path_B OFF
+	PHY_SetBBReg(Adapter, 0xe60, bMaskDWord, 0);
+	PHY_SetBBReg(Adapter, 0xe64, bMaskDWord, 0);
+}
+#endif
+
+int
+PHY_RFConfig8703B(
+	IN	PADAPTER	Adapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	int		rtStatus = _SUCCESS;
+
+	//
+	// RF config
+	//
+	rtStatus = PHY_RF6052_Config8703B(Adapter);
+
+	phy_LCK_8703B(Adapter);
+	//PHY_BB8703B_Config_1T(Adapter);
+
+	return rtStatus;
+}
+
+/*-----------------------------------------------------------------------------
+ * Function:    PHY_ConfigRFWithParaFile()
+ *
+ * Overview:    This function read RF parameters from general file format, and do RF 3-wire
+ *
+ * Input:      	PADAPTER			Adapter
+ *			ps1Byte 				pFileName
+ *			RF_PATH				eRFPath
+ *
+ * Output:      NONE
+ *
+ * Return:      RT_STATUS_SUCCESS: configuration file exist
+ *
+ * Note:		Delay may be required for RF configuration
+ *---------------------------------------------------------------------------*/
+int
+PHY_ConfigRFWithParaFile_8703B(
+	IN	PADAPTER			Adapter,
+	IN	u8* 				pFileName,
+	RF_PATH				eRFPath
+)
+{
+	return _SUCCESS;
+}
+
+//****************************************
+/*-----------------------------------------------------------------------------
+ * Function:    PHY_ConfigRFWithHeaderFile()
+ *
+ * Overview:    This function read RF parameters from general file format, and do RF 3-wire
+ *
+ * Input:      	PADAPTER			Adapter
+ *			ps1Byte 				pFileName
+ *			RF_PATH				eRFPath
+ *
+ * Output:      NONE
+ *
+ * Return:      RT_STATUS_SUCCESS: configuration file exist
+ *
+ * Note:		Delay may be required for RF configuration
+ *---------------------------------------------------------------------------*/
+void phy_PowerIndexCheck8703B(
+	IN	PADAPTER		Adapter,
+	IN	u8			channel,
+	IN OUT u8		*cckPowerLevel,
+	IN OUT u8		*ofdmPowerLevel,
+	IN OUT u8		*BW20PowerLevel,
+	IN OUT u8		*BW40PowerLevel	
+	)
+{
+
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+
+	pHalData->CurrentCckTxPwrIdx = cckPowerLevel[0];
+	pHalData->CurrentOfdm24GTxPwrIdx = ofdmPowerLevel[0];
+	pHalData->CurrentBW2024GTxPwrIdx = BW20PowerLevel[0];
+	pHalData->CurrentBW4024GTxPwrIdx = BW40PowerLevel[0];
+
+	RT_TRACE(_module_hal_init_c_, _drv_info_, 
+		("PHY_SetTxPowerLevel8703B(): CurrentCckTxPwrIdx : 0x%x,CurrentOfdm24GTxPwrIdx: 0x%x\n", 
+		pHalData->CurrentCckTxPwrIdx, pHalData->CurrentOfdm24GTxPwrIdx));
+}
+
+/**************************************************************************************************************
+ *   Description: 
+ *       The low-level interface to set TxAGC , called by both MP and Normal Driver.
+ *
+ *                                                                                    <20120830, Kordan>
+ **************************************************************************************************************/
+
+VOID
+PHY_SetTxPowerIndex_8703B(
+	IN	PADAPTER			Adapter,
+	IN	u32					PowerIndex,
+	IN	u8					RFPath,	
+	IN	u8					Rate
+	)
+{
+	if (RFPath == ODM_RF_PATH_A || RFPath == ODM_RF_PATH_B)
+	{
+		switch (Rate)
+		{
+			case MGN_1M:    PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32,      bMaskByte1, PowerIndex); break;
+			case MGN_2M:    PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1, PowerIndex); break;
+			case MGN_5_5M:  PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte2, PowerIndex); break;
+			case MGN_11M:   PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte3, PowerIndex); break;
+
+			case MGN_6M:    PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte0, PowerIndex); break;
+			case MGN_9M:    PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte1, PowerIndex); break;
+			case MGN_12M:   PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte2, PowerIndex); break;
+			case MGN_18M:   PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte3, PowerIndex); break;
+
+			case MGN_24M:   PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte0, PowerIndex); break;
+			case MGN_36M:   PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte1, PowerIndex); break;
+			case MGN_48M:   PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte2, PowerIndex); break;
+			case MGN_54M:   PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte3, PowerIndex); break;
+
+			case MGN_MCS0:  PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte0, PowerIndex); break;
+			case MGN_MCS1:  PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte1, PowerIndex); break;
+			case MGN_MCS2:  PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte2, PowerIndex); break;
+			case MGN_MCS3:  PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte3, PowerIndex); break;
+
+			case MGN_MCS4:  PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte0, PowerIndex); break;
+			case MGN_MCS5:  PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte1, PowerIndex); break;
+			case MGN_MCS6:  PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte2, PowerIndex); break;
+			case MGN_MCS7:  PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte3, PowerIndex); break;
+
+			default:
+			     DBG_871X("Invalid Rate!!\n");
+			     break;
+		}
+	}
+	else
+	{
+		RT_TRACE(_module_hal_init_c_, _drv_err_,("Invalid RFPath!!\n"));
+	}
+}
+
+u8
+phy_GetCurrentTxNum_8703B(
+	IN	PADAPTER		pAdapter
+	)
+{
+	return RF_TX_NUM_NONIMPLEMENT;
+}
+
+u8
+PHY_GetTxPowerIndex_8703B(
+	IN	PADAPTER			pAdapter,
+	IN	u8					RFPath,
+	IN	u8					Rate,	
+	IN	CHANNEL_WIDTH		BandWidth,	
+	IN	u8					Channel
+	)
+{
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(pAdapter);
+	s8					txPower = 0, powerDiffByRate = 0, limit = 0;
+	BOOLEAN				bIn24G = _FALSE;
+
+	//DBG_871X("===>%s\n", __FUNCTION__ );
+	
+	txPower = (s8) PHY_GetTxPowerIndexBase( pAdapter,RFPath, Rate, BandWidth, Channel, &bIn24G );
+	powerDiffByRate = PHY_GetTxPowerByRate( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, Rate );
+
+	limit = PHY_GetTxPowerLimit( pAdapter, pAdapter->registrypriv.RegPwrTblSel, (u8)(!bIn24G), pHalData->CurrentChannelBW, RFPath, Rate, pHalData->CurrentChannel);
+
+	powerDiffByRate = powerDiffByRate > limit ? limit : powerDiffByRate;
+	txPower += powerDiffByRate;
+	
+	txPower += PHY_GetTxPowerTrackingOffset( pAdapter, RFPath, Rate );
+
+	if(txPower > MAX_POWER_INDEX)
+		txPower = MAX_POWER_INDEX;
+
+	//DBG_871X("Final Tx Power(RF-%c, Channel: %d) = %d(0x%X)\n", ((RFPath==0)?'A':'B'), Channel, txPower, txPower));
+	return (u8) txPower;	
+}
+
+VOID
+PHY_SetTxPowerLevel8703B(
+	IN	PADAPTER		Adapter,
+	IN	u8				Channel
+	)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	PDM_ODM_T		pDM_Odm = &pHalData->odmpriv;
+	pFAT_T			pDM_FatTable = &pDM_Odm->DM_FatTable;
+	u8				RFPath = ODM_RF_PATH_A; 
+
+	if(pHalData->AntDivCfg){// antenna diversity Enable
+		RFPath = ( (pDM_FatTable->RxIdleAnt == MAIN_ANT) ? ODM_RF_PATH_A : ODM_RF_PATH_B);
+	}
+	else{ // antenna diversity disable
+		RFPath = pHalData->ant_path;
+	}
+
+	RT_TRACE(_module_hal_init_c_, _drv_info_,("==>PHY_SetTxPowerLevel8703B()\n"));
+
+	PHY_SetTxPowerLevelByPath(Adapter, Channel, RFPath);
+
+	RT_TRACE(_module_hal_init_c_, _drv_info_,("<==PHY_SetTxPowerLevel8703B()\n"));
+}
+
+VOID
+PHY_GetTxPowerLevel8703B(
+	IN	PADAPTER		Adapter,
+	OUT s32*		    		powerlevel
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	s32				TxPwrDbm = 13;
+#if 0
+	RT_TRACE(COMP_TXAGC, DBG_LOUD, ("PHY_GetTxPowerLevel8703B(): TxPowerLevel: %#x\n", TxPwrDbm));
+
+	if ( pMgntInfo->ClientConfigPwrInDbm != UNSPECIFIED_PWR_DBM )
+		*powerlevel = pMgntInfo->ClientConfigPwrInDbm;
+	else
+		*powerlevel = TxPwrDbm;
+#endif
+}
+
+
+// <20130321, VincentLan> A workaround to eliminate the 2440MHz & 2480MHz spur of 8703B. (Asked by Rock.)
+VOID
+phy_SpurCalibration_8703B(
+	IN	PADAPTER					pAdapter,
+	IN	u1Byte						ToChannel,
+	IN	u1Byte						threshold
+	)
+{
+	u4Byte 		freq[6] = {0xFCCD, 0xFC4D, 0xFFCD, 0xFF4D, 0xFCCD, 0xFF9A}; // {chnl 5, 6, 7, 8, 13, 14}
+	u1Byte 		idx = 0;
+	u1Byte		b_doNotch = FALSE;
+	u1Byte 		initial_gain;
+	BOOLEAN		bHW_Ctrl = FALSE, bSW_Ctrl = FALSE,bHW_Ctrl_S1 = FALSE, bSW_Ctrl_S1 = FALSE;
+	u4Byte		reg948;
+
+	// add for notch
+	u4Byte				wlan_channel, CurrentChannel, Is40MHz;
+	HAL_DATA_TYPE		*pHalData	= GET_HAL_DATA(pAdapter);
+	//PMGNT_INFO			pMgntInfo = &(pAdapter->MgntInfo);
+	PDM_ODM_T		pDM_Odm = &(pHalData->odmpriv);
+	//PDM_ODM_T			pDM_Odm = &pHalData->DM_OutSrc;
+
+	// check threshold
+	if(threshold <= 0x0)
+		threshold = 0x16;
+
+	DBG_8192C("===>phy_SpurCalibration_8703B: Channel = %d\n", ToChannel);
+
+	if (ToChannel == 5)
+		idx = 0;
+	else if (ToChannel == 6)
+		idx = 1;
+	else if (ToChannel == 7)
+		idx = 2;
+	else if (ToChannel == 8)
+		idx = 3;
+	else if (ToChannel == 13)
+		idx = 4;
+	else if (ToChannel == 14)
+		idx = 5;
+	else
+		idx = 10;
+
+	reg948 = PHY_QueryBBReg(pAdapter, rS0S1_PathSwitch, bMaskDWord);
+	if((reg948 & BIT6) == 0x0)
+		bSW_Ctrl = TRUE;
+	else
+		bHW_Ctrl = TRUE;
+
+	if(bHW_Ctrl)
+		bHW_Ctrl_S1 = (PHY_QueryBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT5|BIT4|BIT3)==0x1)? TRUE:FALSE;
+	else if(bSW_Ctrl)
+		bSW_Ctrl_S1 = ((reg948 & BIT9) == 0x0)? TRUE:FALSE;
+
+	// If wlan at S1 (both HW control & SW control) and current channel=5,6,7,8,13,14
+	if ((bHW_Ctrl_S1 || bSW_Ctrl_S1) && (idx <= 5)) 
+	{
+		initial_gain = (u1Byte) (ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskByte0) & 0x7f);
+		ODM_Write_DIG(pDM_Odm, 0x30);
+		PHY_SetBBReg(pAdapter, rFPGA0_AnalogParameter4, bMaskDWord, 0xccf000c0); 		// disable 3-wire
+
+		PHY_SetBBReg(pAdapter, rFPGA0_PSDFunction, bMaskDWord, freq[idx]); 				// Setup PSD
+		PHY_SetBBReg(pAdapter, rFPGA0_PSDFunction, bMaskDWord, 0x400000 | freq[idx]); // Start PSD	
+
+		rtw_msleep_os(30);
+
+		if(PHY_QueryBBReg(pAdapter, rFPGA0_PSDReport, bMaskDWord) >= threshold)
+			b_doNotch = TRUE;
+		
+		PHY_SetBBReg(pAdapter, rFPGA0_PSDFunction, bMaskDWord, freq[idx]); // turn off PSD
+		PHY_SetBBReg(pAdapter, rFPGA0_AnalogParameter4, bMaskDWord, 0xccc000c0); 	// enable 3-wire
+		ODM_Write_DIG(pDM_Odm, initial_gain);
+	}
+
+	// --- Notch Filter --- Asked by Rock	
+ 	if (b_doNotch)
+	{
+		CurrentChannel = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask);  
+		wlan_channel   = CurrentChannel & 0x0f;						    //Get center frequency
+
+		switch(wlan_channel)								    				//Set notch filter				
+		{
+			case 5:
+			case 13:
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT28|BIT27|BIT26|BIT25|BIT24, 0xB);
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1);                     	//enable notch filter
+				ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x06000000);
+				ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1);                    	//enable CSI mask
+				break;
+			case 6:
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT28|BIT27|BIT26|BIT25|BIT24, 0x4);
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1);                   	 	//enable notch filter
+				ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x00000600);
+				ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1);                    	//enable CSI mask
+				break;
+			case 7:
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT28|BIT27|BIT26|BIT25|BIT24, 0x3);
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1);                    	//enable notch filter
+				ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x06000000);
+				ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1);                   	//enable CSI mask
+				break;
+			case 8:
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT28|BIT27|BIT26|BIT25|BIT24, 0xA);
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1);                    	//enable notch filter
+				ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x00000380);
+				ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1);                   	//enable CSI mask
+				break;
+			case 14:
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT28|BIT27|BIT26|BIT25|BIT24, 0x5);
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1);                   	 	//enable notch filter
+				ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000);
+				ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x00180000);
+				ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1);                    	//enable CSI mask
+				break;
+			default:
+				ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x0);				//disable notch filter
+				ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x0);                    	//disable CSI mask	function
+				break;
+		}//switch(wlan_channel)	
+		return;
+	}
+
+	ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x0);                     //disable notch filter
+	ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x0);                    //disable CSI mask
+
+}
+
+VOID
+phy_SetRegBW_8703B(
+	IN	PADAPTER		Adapter,
+	CHANNEL_WIDTH 	CurrentBW
+)	
+{
+	u16	RegRfMod_BW, u2tmp = 0;
+	RegRfMod_BW = rtw_read16(Adapter, REG_TRXPTCL_CTL_8703B);
+
+	switch(CurrentBW)
+	{
+		case CHANNEL_WIDTH_20:
+			rtw_write16(Adapter, REG_TRXPTCL_CTL_8703B, (RegRfMod_BW & 0xFE7F)); // BIT 7 = 0, BIT 8 = 0
+			break;
+
+		case CHANNEL_WIDTH_40:
+			u2tmp = RegRfMod_BW | BIT7;
+			rtw_write16(Adapter, REG_TRXPTCL_CTL_8703B, (u2tmp & 0xFEFF)); // BIT 7 = 1, BIT 8 = 0
+			break;
+
+		case CHANNEL_WIDTH_80:
+			u2tmp = RegRfMod_BW | BIT8;
+			rtw_write16(Adapter, REG_TRXPTCL_CTL_8703B, (u2tmp & 0xFF7F)); // BIT 7 = 0, BIT 8 = 1
+			break;
+
+		default:
+			DBG_871X("phy_PostSetBWMode8703B():	unknown Bandwidth: %#X\n",CurrentBW);
+			break;
+	}
+}
+
+u8 
+phy_GetSecondaryChnl_8703B(
+	IN	PADAPTER	Adapter
+)
+{
+	u8	SCSettingOf40 = 0, SCSettingOf20 = 0;
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+
+	RT_TRACE(_module_hal_init_c_, _drv_info_,("SCMapping: VHT Case: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC));
+	if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_80)
+	{
+		if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
+			SCSettingOf40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
+		else if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
+			SCSettingOf40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
+		else
+			RT_TRACE(_module_hal_init_c_, _drv_err_,("SCMapping: Not Correct Primary40MHz Setting \n"));
+		
+		if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
+			SCSettingOf20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
+		else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
+			SCSettingOf20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
+		else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
+			SCSettingOf20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
+		else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
+			SCSettingOf20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
+		else
+			RT_TRACE(_module_hal_init_c_, _drv_err_,("SCMapping: Not Correct Primary40MHz Setting \n"));
+	}
+	else if(pHalData->CurrentChannelBW == CHANNEL_WIDTH_40)
+	{
+		RT_TRACE(_module_hal_init_c_, _drv_info_,("SCMapping: VHT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur40MhzPrimeSC));
+
+		if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
+			SCSettingOf20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
+		else if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
+			SCSettingOf20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
+		else
+			RT_TRACE(_module_hal_init_c_, _drv_err_,("SCMapping: Not Correct Primary40MHz Setting \n"));
+	}
+
+	RT_TRACE(_module_hal_init_c_, _drv_info_,("SCMapping: SC Value %x \n", ( (SCSettingOf40 << 4) | SCSettingOf20)));
+	return  ( (SCSettingOf40 << 4) | SCSettingOf20);
+}
+
+VOID
+phy_PostSetBwMode8703B(
+	IN	PADAPTER	Adapter
+)
+{
+	u1Byte			SubChnlNum = 0;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	u1Byte			u1TmpVal = 0;
+
+	//3 Set Reg668 Reg440 BW
+	phy_SetRegBW_8703B(Adapter, pHalData->CurrentChannelBW);
+
+	//3 Set Reg483
+	SubChnlNum = phy_GetSecondaryChnl_8703B(Adapter);
+	rtw_write8(Adapter, REG_DATA_SC_8703B, SubChnlNum);
+	
+	//3//
+	//3//<2>Set PHY related register
+	//3//
+	switch(pHalData->CurrentChannelBW)
+	{
+		/* 20 MHz channel*/
+		case CHANNEL_WIDTH_20:
+			PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
+			
+			PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
+			
+//			PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT10, 1);
+			
+			PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, (BIT31|BIT30), 0x0);
+
+			/* 8703B new Add */
+			PHY_SetBBReg(Adapter, pHalData->RegForRecover[2].offset, bMaskDWord, pHalData->RegForRecover[2].value);
+			PHY_SetBBReg(Adapter, pHalData->RegForRecover[3].offset, bMaskDWord, pHalData->RegForRecover[3].value);
+			PHY_SetRFReg(Adapter, ODM_RF_PATH_A, pHalData->RegForRecover[4].offset, bRFRegOffsetMask, pHalData->RegForRecover[4].value);
+
+			break;
+
+
+		/* 40 MHz channel*/
+		case CHANNEL_WIDTH_40:
+			PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
+			
+			PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
+
+			/* 8703B new Add*/
+			PHY_SetBBReg(Adapter, rBBrx_DFIR, bMaskDWord, 0x40100000);
+			PHY_SetBBReg(Adapter, rOFDM0_XATxAFE, bMaskDWord, 0x51F60000);
+			PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1E, bRFRegOffsetMask, 0x00C4C);
+
+			/* Set Control channel to upper or lower. These settings are required only for 40MHz*/
+			PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC>>1));
+
+			PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
+
+			PHY_SetBBReg(Adapter, 0x818, (BIT26|BIT27), (pHalData->nCur40MhzPrimeSC==HAL_PRIME_CHNL_OFFSET_LOWER)?2:1);
+
+			u1TmpVal = rtw_read8(Adapter, REG_DATA_SC_8703B);
+			u1TmpVal &= 0xF0;
+			u1TmpVal |= ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
+			rtw_write8(Adapter, REG_DATA_SC_8703B, u1TmpVal);
+
+			break;
+
+
+			
+		default:
+			/*RT_TRACE(COMP_DBG, DBG_LOUD, ("phy_SetBWMode8703B(): unknown Bandwidth: %#X\n"\
+						,pHalData->CurrentChannelBW));*/
+			break;
+			
+	}
+
+	//3<3>Set RF related register
+	PHY_RF6052SetBandwidth8703B(Adapter, pHalData->CurrentChannelBW);
+}
+
+VOID
+phy_SwChnl8703B(	
+	IN	PADAPTER					pAdapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
+	u8 			channelToSW = pHalData->CurrentChannel;
+	u8		i = 0;
+
+	if (pHalData->rf_chip == RF_PSEUDO_11N) {
+		DBG_871X("phy_SwChnl8703B: return for PSEUDO\n");
+		return;
+	}
+	
+	pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff00) | channelToSW  );
+	PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0] );
+	PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0] );
+
+	/* BB Setting for some channels (requested by BB Neil)  */
+	switch (channelToSW) {
+	case 14:
+		/*Channel 14 in CCK, need to set 0xA26~0xA29 to 0 */
+		PHY_SetBBReg(pAdapter, rCCK0_TxFilter2, bMaskHWord, 0);
+		PHY_SetBBReg(pAdapter, rCCK0_DebugPort, bMaskLWord, 0);
+		break;
+	default:
+		/*Normal setting for 8703B, just recover to the default setting. */
+		/*This hardcore values refer to the parameter which BB team gave. */
+		for (i = 0 ; i < 2 ; ++i)
+			PHY_SetBBReg(pAdapter, pHalData->RegForRecover[i].offset, bMaskDWord, pHalData->RegForRecover[i].value);
+	}
+	
+	phy_SpurCalibration_8703B(pAdapter, channelToSW, 0x16);
+
+	DBG_8192C("===>phy_SwChnl8703B: Channel = %d\n", channelToSW);
+}
+
+VOID
+phy_SwChnlAndSetBwMode8703B(
+	IN  PADAPTER		Adapter
+)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+
+	//RT_TRACE(COMP_SCAN, DBG_LOUD, ("phy_SwChnlAndSetBwMode8703B(): bSwChnl %d, bSetChnlBW %d \n", pHalData->bSwChnl, pHalData->bSetChnlBW));
+	if ( Adapter->bNotifyChannelChange )
+	{
+		DBG_871X( "[%s] bSwChnl=%d, ch=%d, bSetChnlBW=%d, bw=%d\n", 
+			__FUNCTION__, 
+			pHalData->bSwChnl,
+			pHalData->CurrentChannel,
+			pHalData->bSetChnlBW,
+			pHalData->CurrentChannelBW);
+	}
+
+	if (RTW_CANNOT_RUN(Adapter))
+		return;
+
+	if(pHalData->bSwChnl)
+	{
+		phy_SwChnl8703B(Adapter);
+		pHalData->bSwChnl = _FALSE;
+	}	
+
+	if(pHalData->bSetChnlBW)
+	{
+		phy_PostSetBwMode8703B(Adapter);
+		pHalData->bSetChnlBW = _FALSE;
+	}	
+
+	PHY_SetTxPowerLevel8703B(Adapter, pHalData->CurrentChannel);
+}
+
+VOID
+PHY_HandleSwChnlAndSetBW8703B(
+	IN	PADAPTER			Adapter,
+	IN	BOOLEAN				bSwitchChannel,
+	IN	BOOLEAN				bSetBandWidth,
+	IN	u8					ChannelNum,
+	IN	CHANNEL_WIDTH	ChnlWidth,
+	IN	EXTCHNL_OFFSET	ExtChnlOffsetOf40MHz,
+	IN	EXTCHNL_OFFSET	ExtChnlOffsetOf80MHz,
+	IN	u8					CenterFrequencyIndex1
+)
+{
+	//static BOOLEAN		bInitialzed = _FALSE;
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(Adapter);
+	u8					tmpChannel = pHalData->CurrentChannel;
+	CHANNEL_WIDTH 	tmpBW= pHalData->CurrentChannelBW;
+	u8					tmpnCur40MhzPrimeSC = pHalData->nCur40MhzPrimeSC;
+	u8					tmpnCur80MhzPrimeSC = pHalData->nCur80MhzPrimeSC;
+	u8					tmpCenterFrequencyIndex1 =pHalData->CurrentCenterFrequencyIndex1;
+	struct mlme_ext_priv	*pmlmeext = &Adapter->mlmeextpriv;
+
+	//DBG_871X("=> PHY_HandleSwChnlAndSetBW8812: bSwitchChannel %d, bSetBandWidth %d \n",bSwitchChannel,bSetBandWidth);
+
+	//check is swchnl or setbw
+	if(!bSwitchChannel && !bSetBandWidth)
+	{
+		DBG_871X("PHY_HandleSwChnlAndSetBW8812:  not switch channel and not set bandwidth \n");
+		return;
+	}
+
+	//skip change for channel or bandwidth is the same
+	if(bSwitchChannel)
+	{
+		//if(pHalData->CurrentChannel != ChannelNum)
+		{
+			if (HAL_IsLegalChannel(Adapter, ChannelNum))
+				pHalData->bSwChnl = _TRUE;
+		}
+	}
+
+	if(bSetBandWidth)
+	{
+		#if 0
+		if(bInitialzed == _FALSE)
+		{
+			bInitialzed = _TRUE;
+			pHalData->bSetChnlBW = _TRUE;
+		}
+		else if((pHalData->CurrentChannelBW != ChnlWidth) ||(pHalData->nCur40MhzPrimeSC != ExtChnlOffsetOf40MHz) || (pHalData->CurrentCenterFrequencyIndex1!= CenterFrequencyIndex1))
+		{
+			pHalData->bSetChnlBW = _TRUE;
+		}
+		#else
+			pHalData->bSetChnlBW = _TRUE;
+		#endif
+	}
+
+	if(!pHalData->bSetChnlBW && !pHalData->bSwChnl)
+	{
+		//DBG_871X("<= PHY_HandleSwChnlAndSetBW8812: bSwChnl %d, bSetChnlBW %d \n",pHalData->bSwChnl,pHalData->bSetChnlBW);
+		return;
+	}
+
+
+	if(pHalData->bSwChnl)
+	{
+		pHalData->CurrentChannel=ChannelNum;
+		pHalData->CurrentCenterFrequencyIndex1 = ChannelNum;
+	}
+	
+
+	if(pHalData->bSetChnlBW)
+	{
+		pHalData->CurrentChannelBW = ChnlWidth;
+#if 0
+		if(ExtChnlOffsetOf40MHz==EXTCHNL_OFFSET_LOWER)
+			pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
+		else if(ExtChnlOffsetOf40MHz==EXTCHNL_OFFSET_UPPER)
+			pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
+		else
+			pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+
+		if(ExtChnlOffsetOf80MHz==EXTCHNL_OFFSET_LOWER)
+			pHalData->nCur80MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
+		else if(ExtChnlOffsetOf80MHz==EXTCHNL_OFFSET_UPPER)
+			pHalData->nCur80MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
+		else
+			pHalData->nCur80MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+#else
+		pHalData->nCur40MhzPrimeSC = ExtChnlOffsetOf40MHz;
+		pHalData->nCur80MhzPrimeSC = ExtChnlOffsetOf80MHz;
+#endif
+
+		pHalData->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1;		
+	}
+
+	//Switch workitem or set timer to do switch channel or setbandwidth operation
+	if (!RTW_CANNOT_RUN(Adapter))
+		phy_SwChnlAndSetBwMode8703B(Adapter);
+	else
+	{
+		if(pHalData->bSwChnl)
+		{
+			pHalData->CurrentChannel = tmpChannel;
+			pHalData->CurrentCenterFrequencyIndex1 = tmpChannel;
+		}	
+		if(pHalData->bSetChnlBW)
+		{
+			pHalData->CurrentChannelBW = tmpBW;
+			pHalData->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC;
+			pHalData->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC;
+			pHalData->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1;
+		}
+	}
+
+	//DBG_871X("Channel %d ChannelBW %d ",pHalData->CurrentChannel, pHalData->CurrentChannelBW);
+	//DBG_871X("40MhzPrimeSC %d 80MhzPrimeSC %d ",pHalData->nCur40MhzPrimeSC, pHalData->nCur80MhzPrimeSC);
+	//DBG_871X("CenterFrequencyIndex1 %d \n",pHalData->CurrentCenterFrequencyIndex1);
+
+	//DBG_871X("<= PHY_HandleSwChnlAndSetBW8812: bSwChnl %d, bSetChnlBW %d \n",pHalData->bSwChnl,pHalData->bSetChnlBW);
+
+}
+
+VOID
+PHY_SetBWMode8703B(
+	IN	PADAPTER					Adapter,
+	IN	CHANNEL_WIDTH	Bandwidth,	// 20M or 40M
+	IN	unsigned char	Offset		// Upper, Lower, or Don't care
+)
+{
+	PHAL_DATA_TYPE		pHalData = GET_HAL_DATA(Adapter);
+
+	PHY_HandleSwChnlAndSetBW8703B(Adapter, _FALSE, _TRUE, pHalData->CurrentChannel, Bandwidth, Offset, Offset, pHalData->CurrentChannel);
+}
+
+VOID
+PHY_SwChnl8703B(	// Call after initialization
+	IN	PADAPTER	Adapter,
+	IN	u8		channel
+	)
+{
+	PHY_HandleSwChnlAndSetBW8703B(Adapter, _TRUE, _FALSE, channel, 0, 0, 0, channel);
+}
+
+VOID
+PHY_SetSwChnlBWMode8703B(
+	IN	PADAPTER			Adapter,
+	IN	u8					channel,
+	IN	CHANNEL_WIDTH	Bandwidth,
+	IN	u8					Offset40,
+	IN	u8					Offset80
+)
+{
+	//DBG_871X("%s()===>\n",__FUNCTION__);
+
+	PHY_HandleSwChnlAndSetBW8703B(Adapter, _TRUE, _TRUE, channel, Bandwidth, Offset40, Offset80, channel);
+
+	//DBG_871X("<==%s()\n",__FUNCTION__);
+}
+
+static VOID
+_PHY_DumpRFReg_8703B(IN	PADAPTER	pAdapter)
+{
+	u32 rfRegValue,rfRegOffset;
+
+	RT_TRACE(_module_hal_init_c_, _drv_info_, ("_PHY_DumpRFReg_8703B()====>\n"));
+
+	for(rfRegOffset = 0x00;rfRegOffset<=0x30;rfRegOffset++){
+		rfRegValue = PHY_QueryRFReg_8703B(pAdapter,RF_PATH_A, rfRegOffset, bMaskDWord);
+		RT_TRACE(_module_hal_init_c_, _drv_info_, (" 0x%02x = 0x%08x\n",rfRegOffset,rfRegValue));
+	}
+	RT_TRACE(_module_hal_init_c_, _drv_info_, ("<===== _PHY_DumpRFReg_8703B()\n"));
+}
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_rf6052.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_rf6052.c
new file mode 100644
index 000000000..c7c102678
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_rf6052.c
@@ -0,0 +1,268 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *
+ * Module:	rtl8192c_rf6052.c	( Source C File)
+ *
+ * Note:	Provide RF 6052 series relative API.
+ *
+ * Function:
+ *
+ * Export:
+ *
+ * Abbrev:
+ *
+ * History:
+ * Data			Who		Remark
+ *
+ * 09/25/2008	MHC		Create initial version.
+ * 11/05/2008 	MHC		Add API for tw power setting.
+ *
+ *
+******************************************************************************/
+
+#include <rtl8703b_hal.h>
+
+/*---------------------------Define Local Constant---------------------------*/
+/*---------------------------Define Local Constant---------------------------*/
+
+
+/*------------------------Define global variable-----------------------------*/
+/*------------------------Define global variable-----------------------------*/
+
+
+/*------------------------Define local variable------------------------------*/
+// 2008/11/20 MH For Debug only, RF
+//static	RF_SHADOW_T	RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG] = {0};
+static	RF_SHADOW_T	RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG];
+/*------------------------Define local variable------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * Function:    PHY_RF6052SetBandwidth()
+ *
+ * Overview:    This function is called by SetBWModeCallback8190Pci() only
+ *
+ * Input:       PADAPTER				Adapter
+ *			WIRELESS_BANDWIDTH_E	Bandwidth	//20M or 40M
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Note:		For RF type 0222D
+ *---------------------------------------------------------------------------*/
+VOID
+PHY_RF6052SetBandwidth8703B(
+	IN	PADAPTER				Adapter,
+	IN	CHANNEL_WIDTH		Bandwidth)	//20M or 40M
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+
+	switch(Bandwidth)
+	{
+		case CHANNEL_WIDTH_20:
+			pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT10 | BIT11 );
+			PHY_SetRFReg(Adapter, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]);
+			PHY_SetRFReg(Adapter, ODM_RF_PATH_B, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]);
+			break;
+
+		case CHANNEL_WIDTH_40:
+			pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT10 );
+			PHY_SetRFReg(Adapter, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]);
+			PHY_SetRFReg(Adapter, ODM_RF_PATH_B, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]);
+			break;
+
+		default:
+			//RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth ));
+			break;
+	}
+
+}
+
+static VOID
+phy_RF6052_Config_HardCode(
+	IN	PADAPTER		Adapter
+	)
+{
+
+	// Set Default Bandwidth to 20M
+	//Adapter->HalFunc	.SetBWModeHandler(Adapter, CHANNEL_WIDTH_20);
+
+	// TODO: Set Default Channel to channel one for RTL8225
+
+}
+
+static int
+phy_RF6052_Config_ParaFile(
+	IN	PADAPTER		Adapter
+	)
+{
+	u32					u4RegValue=0;
+	u8					eRFPath;
+	BB_REGISTER_DEFINITION_T	*pPhyReg;
+
+	int					rtStatus = _SUCCESS;
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
+
+	static char			sz8703RadioAFile[] = RTL8703B_PHY_RADIO_A;
+	static char			sz8703RadioBFile[] = RTL8703B_PHY_RADIO_B;
+	static s1Byte 			sz8703BTxPwrTrackFile[] = RTL8703B_TXPWR_TRACK;	
+	char					*pszRadioAFile, *pszRadioBFile, *pszTxPwrTrackFile;
+
+	pszRadioAFile = sz8703RadioAFile;
+	pszRadioBFile = sz8703RadioBFile;
+	pszTxPwrTrackFile = sz8703BTxPwrTrackFile;
+
+	//3//-----------------------------------------------------------------
+	//3// <2> Initialize RF
+	//3//-----------------------------------------------------------------
+	//for(eRFPath = RF_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+	for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+	{
+
+		pPhyReg = &pHalData->PHYRegDef[eRFPath];
+
+		/*----Store original RFENV control type----*/
+		switch(eRFPath)
+		{
+		case RF_PATH_A:
+		case RF_PATH_C:
+			u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV);
+			break;
+		case RF_PATH_B :
+		case RF_PATH_D:
+			u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16);
+			break;
+		}
+
+		/*----Set RF_ENV enable----*/
+		PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
+		rtw_udelay_os(1);//PlatformStallExecution(1);
+
+		/*----Set RF_ENV output high----*/
+		PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
+		rtw_udelay_os(1);//PlatformStallExecution(1);
+
+		/* Set bit number of Address and Data for RF register */
+		PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); 	// Set 1 to 4 bits for 8255
+		rtw_udelay_os(1);//PlatformStallExecution(1);
+
+		PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0);	// Set 0 to 12  bits for 8255
+		rtw_udelay_os(1);//PlatformStallExecution(1);
+
+		/*----Initialize RF fom connfiguration file----*/
+		switch(eRFPath)
+		{
+		case RF_PATH_A:
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+			if (PHY_ConfigRFWithParaFile(Adapter, pszRadioAFile, eRFPath) == _FAIL)
+#endif
+			{
+#ifdef CONFIG_EMBEDDED_FWIMG
+				if(HAL_STATUS_FAILURE ==ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv,CONFIG_RF_RADIO, (ODM_RF_RADIO_PATH_E)eRFPath))
+					rtStatus = _FAIL;
+#endif
+			}
+			break;
+		case RF_PATH_B:
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+			if (PHY_ConfigRFWithParaFile(Adapter, pszRadioBFile, eRFPath) == _FAIL)
+#endif
+			{
+#ifdef CONFIG_EMBEDDED_FWIMG
+				if(HAL_STATUS_FAILURE ==ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv,CONFIG_RF_RADIO, (ODM_RF_RADIO_PATH_E)eRFPath))
+					rtStatus = _FAIL;
+#endif
+			}
+			break;
+		case RF_PATH_C:
+			break;
+		case RF_PATH_D:
+			break;
+		}
+
+		/*----Restore RFENV control type----*/;
+		switch(eRFPath)
+		{
+		case RF_PATH_A:
+		case RF_PATH_C:
+			PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
+			break;
+		case RF_PATH_B :
+		case RF_PATH_D:
+			PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
+			break;
+		}
+
+		if(rtStatus != _SUCCESS){
+			//RT_TRACE(COMP_FPGA, DBG_LOUD, ("phy_RF6052_Config_ParaFile():Radio[%d] Fail!!", eRFPath));
+			goto phy_RF6052_Config_ParaFile_Fail;
+		}
+
+	}
+
+	//3 -----------------------------------------------------------------
+	//3 Configuration of Tx Power Tracking 
+	//3 -----------------------------------------------------------------
+	
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+	if (PHY_ConfigRFWithTxPwrTrackParaFile(Adapter, pszTxPwrTrackFile) == _FAIL)
+#endif
+	{
+#ifdef CONFIG_EMBEDDED_FWIMG
+		ODM_ConfigRFWithTxPwrTrackHeaderFile(&pHalData->odmpriv);
+#endif
+	}
+	
+	//RT_TRACE(COMP_INIT, DBG_LOUD, ("<---phy_RF6052_Config_ParaFile()\n"));
+	return rtStatus;
+
+phy_RF6052_Config_ParaFile_Fail:
+	return rtStatus;
+}
+
+
+int
+PHY_RF6052_Config8703B(
+	IN	PADAPTER		Adapter)
+{
+	HAL_DATA_TYPE				*pHalData = GET_HAL_DATA(Adapter);
+	int					rtStatus = _SUCCESS;
+
+	//
+	// Initialize general global value
+	//
+	// TODO: Extend RF_PATH_C and RF_PATH_D in the future
+	if(pHalData->rf_type == RF_1T1R)
+		pHalData->NumTotalRFPath = 1;
+	else
+		pHalData->NumTotalRFPath = 2;
+
+	//
+	// Config BB and RF
+	//
+	rtStatus = phy_RF6052_Config_ParaFile(Adapter);
+	return rtStatus;
+
+}
+
+/* End of HalRf6052.c */
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_rxdesc.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_rxdesc.c
new file mode 100644
index 000000000..3e7b21a73
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_rxdesc.c
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#define _RTL8703B_REDESC_C_
+
+#include <rtl8703b_hal.h>
+
+void rtl8703b_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc)
+{
+	struct rx_pkt_attrib *pattrib;
+
+
+	pattrib = &precvframe->u.hdr.attrib;
+	_rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
+
+	pattrib->pkt_len = (u16)GET_RX_STATUS_DESC_PKT_LEN_8703B(pdesc);
+	pattrib->pkt_rpt_type = GET_RX_STATUS_DESC_RPT_SEL_8703B(pdesc) ? C2H_PACKET : NORMAL_RX;
+
+	if (pattrib->pkt_rpt_type == NORMAL_RX) {
+		// Offset 0
+		pattrib->crc_err = (u8)GET_RX_STATUS_DESC_CRC32_8703B(pdesc);
+		pattrib->icv_err = (u8)GET_RX_STATUS_DESC_ICV_8703B(pdesc);
+		pattrib->drvinfo_sz = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE_8703B(pdesc) << 3;
+		pattrib->encrypt = (u8)GET_RX_STATUS_DESC_SECURITY_8703B(pdesc);
+		pattrib->qos = (u8)GET_RX_STATUS_DESC_QOS_8703B(pdesc);
+		pattrib->shift_sz = (u8)GET_RX_STATUS_DESC_SHIFT_8703B(pdesc);
+		pattrib->physt = (u8)GET_RX_STATUS_DESC_PHY_STATUS_8703B(pdesc);
+		pattrib->bdecrypted = (u8)GET_RX_STATUS_DESC_SWDEC_8703B(pdesc) ? 0 : 1;
+
+		// Offset 4
+		pattrib->priority = (u8)GET_RX_STATUS_DESC_TID_8703B(pdesc);
+		pattrib->amsdu = (u8)GET_RX_STATUS_DESC_AMSDU_8703B(pdesc);
+		pattrib->mdata = (u8)GET_RX_STATUS_DESC_MORE_DATA_8703B(pdesc);
+		pattrib->mfrag = (u8)GET_RX_STATUS_DESC_MORE_FRAG_8703B(pdesc);
+
+		// Offset 8
+		pattrib->seq_num = (u16)GET_RX_STATUS_DESC_SEQ_8703B(pdesc);
+		pattrib->frag_num = (u8)GET_RX_STATUS_DESC_FRAG_8703B(pdesc);
+
+		// Offset 12
+		pattrib->data_rate = (u8)GET_RX_STATUS_DESC_RX_RATE_8703B(pdesc);
+
+		/* Offset 16 */
+		pattrib->sgi = (u8)GET_RX_STATUS_DESC_SPLCP_8703B(pdesc);
+		pattrib->ldpc = (u8)GET_RX_STATUS_DESC_LDPC_8703B(pdesc);
+		pattrib->stbc = (u8)GET_RX_STATUS_DESC_STBC_8703B(pdesc);
+		pattrib->bw = (u8)GET_RX_STATUS_DESC_BW_8703B(pdesc);
+
+		/* Offset 20 */
+		/* pattrib->tsfl=(u8)GET_RX_STATUS_DESC_TSFL_8703B(pdesc); */
+	}
+}
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_sreset.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_sreset.c
new file mode 100644
index 000000000..bb7920b4e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/rtl8703b_sreset.c
@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *
+ ******************************************************************************/
+#define _RTL8703B_SRESET_C_
+
+#include <rtl8703b_hal.h>
+
+
+#ifdef DBG_CONFIG_ERROR_DETECT
+void rtl8703b_sreset_xmit_status_check(_adapter *padapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+
+	unsigned long current_time;
+	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
+	unsigned int diff_time;
+	u32 txdma_status;
+
+	txdma_status=rtw_read32(padapter, REG_TXDMA_STATUS);
+	if( txdma_status !=0x00 && txdma_status !=0xeaeaeaea){
+		DBG_871X("%s REG_TXDMA_STATUS:0x%08x\n", __FUNCTION__, txdma_status);
+		rtw_hal_sreset_reset(padapter);
+	}
+
+#ifdef CONFIG_USB_HCI
+	//total xmit irp = 4
+	//DBG_8192C("==>%s free_xmitbuf_cnt(%d),txirp_cnt(%d)\n",__FUNCTION__,pxmitpriv->free_xmitbuf_cnt,pxmitpriv->txirp_cnt);
+	//if(pxmitpriv->txirp_cnt == NR_XMITBUFF+1)
+	current_time = rtw_get_current_time();
+
+	if(0 == pxmitpriv->free_xmitbuf_cnt || 0 == pxmitpriv->free_xmit_extbuf_cnt) {
+
+		diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_time);
+
+		if (diff_time > 2000) {
+			if (psrtpriv->last_tx_complete_time == 0) {
+				psrtpriv->last_tx_complete_time = current_time;
+			}
+			else{
+				diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_complete_time);
+				if (diff_time > 4000) {
+					u32 ability = 0;
+
+					//padapter->Wifi_Error_Status = WIFI_TX_HANG;
+					ability = rtw_phydm_ability_get(padapter);
+
+					DBG_871X("%s tx hang %s\n", __FUNCTION__,
+						(ability & ODM_BB_ADAPTIVITY)? "ODM_BB_ADAPTIVITY" : "");
+
+					if (!(ability & ODM_BB_ADAPTIVITY))
+						rtw_hal_sreset_reset(padapter);
+				}
+			}
+		}
+	}
+#endif // #ifdef CONFIG_USB_HCI
+
+	if (psrtpriv->dbg_trigger_point == SRESET_TGP_XMIT_STATUS) {
+		psrtpriv->dbg_trigger_point = SRESET_TGP_NULL;
+		rtw_hal_sreset_reset(padapter);
+		return;
+	}
+}
+
+void rtl8703b_sreset_linked_status_check(_adapter *padapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+#if 0
+	u32 regc50,regc58,reg824,reg800;
+	regc50 = rtw_read32(padapter,0xc50);
+	regc58 = rtw_read32(padapter,0xc58);
+	reg824 = rtw_read32(padapter,0x824);
+	reg800 = rtw_read32(padapter,0x800);
+	if(	((regc50&0xFFFFFF00)!= 0x69543400)||
+		((regc58&0xFFFFFF00)!= 0x69543400)||
+		(((reg824&0xFFFFFF00)!= 0x00390000)&&(((reg824&0xFFFFFF00)!= 0x80390000)))||
+		( ((reg800&0xFFFFFF00)!= 0x03040000)&&((reg800&0xFFFFFF00)!= 0x83040000)))
+	{
+		DBG_8192C("%s regc50:0x%08x, regc58:0x%08x, reg824:0x%08x, reg800:0x%08x,\n", __FUNCTION__,
+			regc50, regc58, reg824, reg800);
+		rtw_hal_sreset_reset(padapter);
+	}
+#endif
+
+	if (psrtpriv->dbg_trigger_point == SRESET_TGP_LINK_STATUS) {
+		psrtpriv->dbg_trigger_point = SRESET_TGP_NULL;
+		rtw_hal_sreset_reset(padapter);
+		return;
+	}
+}
+
+#endif
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_led.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_led.c
new file mode 100644
index 000000000..3afd2a92e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_led.c
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *
+ ******************************************************************************/
+#define _RTL8703BS_LED_C_
+
+#include "rtl8703b_hal.h"
+
+//================================================================================
+// LED object.
+//================================================================================
+
+
+//================================================================================
+//	Prototype of protected function.
+//================================================================================
+
+//================================================================================
+// LED_819xUsb routines.
+//================================================================================
+
+//
+//	Description:
+//		Turn on LED according to LedPin specified.
+//
+void
+SwLedOn_8703BS(
+	_adapter			*padapter,
+	PLED_SDIO		pLed
+)
+{
+	u8	LedCfg;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+	if (RTW_CANNOT_RUN(padapter))
+		return;
+
+	pLed->bLedOn = _TRUE;
+
+}
+
+
+//
+//	Description:
+//		Turn off LED according to LedPin specified.
+//
+void
+SwLedOff_8703BS(
+	_adapter			*padapter,
+	PLED_SDIO		pLed
+)
+{
+	u8	LedCfg;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+	if (RTW_CANNOT_RUN(padapter))
+		goto exit;
+
+exit:
+	pLed->bLedOn = _FALSE;
+
+}
+
+//================================================================================
+// Interface to manipulate LED objects.
+//================================================================================
+
+//================================================================================
+// Default LED behavior.
+//================================================================================
+
+//
+//	Description:
+//		Initialize all LED_871x objects.
+//
+void
+rtl8703bs_InitSwLeds(
+	_adapter	*padapter
+	)
+{
+#if 0
+	struct led_priv *pledpriv = &(padapter->ledpriv);
+
+	pledpriv->LedControlHandler = LedControlSDIO;
+
+	pledpriv->SwLedOn = SwLedOn_8703BS;
+	pledpriv->SwLedOff = SwLedOff_8703BS;
+	
+	InitLed871x(padapter, &(pledpriv->SwLed0), LED_PIN_LED0);
+
+	InitLed871x(padapter,&(pledpriv->SwLed1), LED_PIN_LED1);
+#endif
+}
+
+
+//
+//	Description:
+//		DeInitialize all LED_819xUsb objects.
+//
+void
+rtl8703bs_DeInitSwLeds(
+	_adapter	*padapter
+	)
+{
+#if 0
+	struct led_priv	*ledpriv = &(padapter->ledpriv);
+
+	DeInitLed871x( &(ledpriv->SwLed0) );
+	DeInitLed871x( &(ledpriv->SwLed1) );
+#endif
+}
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_recv.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_recv.c
new file mode 100644
index 000000000..75bd5ee2f
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_recv.c
@@ -0,0 +1,711 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *
+ ******************************************************************************/
+#define _RTL8703BS_RECV_C_
+
+#include <rtl8703b_hal.h>
+
+
+static s32 initrecvbuf(struct recv_buf *precvbuf, PADAPTER padapter)
+{
+	_rtw_init_listhead(&precvbuf->list);
+	_rtw_spinlock_init(&precvbuf->recvbuf_lock);
+
+	precvbuf->adapter = padapter;
+
+	return _SUCCESS;
+}
+
+static void freerecvbuf(struct recv_buf *precvbuf)
+{
+	_rtw_spinlock_free(&precvbuf->recvbuf_lock);
+}
+
+static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_buf	*precvbuf, u8 *pphy_status)
+{
+	s32 ret=_SUCCESS;
+#ifdef CONFIG_CONCURRENT_MODE
+	u8 *secondary_myid, *paddr1;
+	union recv_frame	*precvframe_if2 = NULL;
+	_adapter *primary_padapter = precvframe->u.hdr.adapter;
+	_adapter *secondary_padapter = primary_padapter->pbuddy_adapter;
+	struct recv_priv *precvpriv = &primary_padapter->recvpriv;
+	_queue *pfree_recv_queue = &precvpriv->free_recv_queue;
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(primary_padapter);
+
+	if(!secondary_padapter)
+		return ret;
+
+	paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data);
+
+	if(IS_MCAST(paddr1) == _FALSE)//unicast packets
+	{
+		secondary_myid = adapter_mac_addr(secondary_padapter);
+
+		if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN))
+		{
+			//change to secondary interface
+			precvframe->u.hdr.adapter = secondary_padapter;
+		}
+
+		//ret = recv_entry(precvframe);
+
+	}
+	else // Handle BC/MC Packets
+	{
+		//clone/copy to if2
+		_pkt	 *pkt_copy = NULL;
+		struct rx_pkt_attrib *pattrib = NULL;
+
+		precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue);
+
+		if(!precvframe_if2)
+			return _FAIL;
+
+		precvframe_if2->u.hdr.adapter = secondary_padapter;
+		_rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
+		pattrib = &precvframe_if2->u.hdr.attrib;
+
+		//driver need to set skb len for skb_copy().
+		//If skb->len is zero, skb_copy() will not copy data from original skb.
+		skb_put(precvframe->u.hdr.pkt, pattrib->pkt_len);
+
+		pkt_copy = rtw_skb_copy( precvframe->u.hdr.pkt);
+		if (pkt_copy == NULL)
+		{
+			if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
+			{
+				DBG_8192C("pre_recv_entry(): rtw_skb_copy fail , drop frag frame \n");
+				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+				return ret;
+			}
+
+			pkt_copy = rtw_skb_clone( precvframe->u.hdr.pkt);
+			if(pkt_copy == NULL)
+			{
+				DBG_8192C("pre_recv_entry(): rtw_skb_clone fail , drop frame\n");
+				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+				return ret;
+			}
+		}
+
+		pkt_copy->dev = secondary_padapter->pnetdev;
+
+		precvframe_if2->u.hdr.pkt = pkt_copy;
+		precvframe_if2->u.hdr.rx_head = pkt_copy->head;
+		precvframe_if2->u.hdr.rx_data = pkt_copy->data;
+		precvframe_if2->u.hdr.rx_tail = skb_tail_pointer(pkt_copy);
+		precvframe_if2->u.hdr.rx_end = skb_end_pointer(pkt_copy);
+		precvframe_if2->u.hdr.len = pkt_copy->len;
+
+		//recvframe_put(precvframe_if2, pattrib->pkt_len);
+
+		if ( pHalData->ReceiveConfig & RCR_APPFCS)
+			recvframe_pull_tail(precvframe_if2, IEEE80211_FCS_LEN);
+
+		if (pattrib->physt)
+			rx_query_phy_status(precvframe_if2, pphy_status);
+
+		if(rtw_recv_entry(precvframe_if2) != _SUCCESS)
+		{
+			RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
+				("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
+		}
+	}
+
+	if (precvframe->u.hdr.attrib.physt)
+		rx_query_phy_status(precvframe, pphy_status);
+
+	ret = rtw_recv_entry(precvframe);
+#endif
+
+	return ret;
+
+}
+
+#ifdef CONFIG_SDIO_RX_COPY
+static void rtl8703bs_recv_tasklet(void *priv)
+{
+	PADAPTER			padapter;
+	PHAL_DATA_TYPE		pHalData;
+	struct recv_priv		*precvpriv;
+	struct recv_buf 	*precvbuf;
+	union recv_frame		*precvframe;
+	struct recv_frame_hdr	*phdr;
+	struct rx_pkt_attrib	*pattrib;
+	_irqL	irql;
+	u8		*ptr;
+	u32 	pkt_len, pkt_offset, skb_len, alloc_sz;
+	_pkt		*pkt_copy = NULL;
+	u8		shift_sz = 0, rx_report_sz = 0;
+
+
+	padapter = (PADAPTER)priv;
+	pHalData = GET_HAL_DATA(padapter);
+	precvpriv = &padapter->recvpriv;
+
+	do {
+		precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
+		if (NULL == precvbuf) break;
+
+		ptr = precvbuf->pdata;
+
+		while (ptr < precvbuf->ptail)
+		{
+			precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
+			if (precvframe == NULL)
+			{
+				DBG_8192C("%s: no enough recv frame!\n", __FUNCTION__);
+				rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
+
+				// The case of can't allocte recvframe should be temporary,
+				// schedule again and hope recvframe is available next time.
+#ifdef PLATFORM_LINUX
+				tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+				return;
+			}
+
+			//rx desc parsing
+			rtl8703b_query_rx_desc_status(precvframe, ptr);
+
+			pattrib = &precvframe->u.hdr.attrib;
+
+			// fix Hardware RX data error, drop whole recv_buffer
+			if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err)
+			{
+#if !(MP_DRIVER==1)
+				DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
+#endif
+				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+				break;
+			}
+
+			rx_report_sz = RXDESC_SIZE + pattrib->drvinfo_sz;
+			pkt_offset = rx_report_sz + pattrib->shift_sz + pattrib->pkt_len;
+
+			if ((ptr + pkt_offset) > precvbuf->ptail) {
+				DBG_8192C("%s()-%d: : next pkt len(%p,%d) exceed ptail(%p)!\n", __FUNCTION__, __LINE__, ptr, pkt_offset, precvbuf->ptail);
+				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+				break;
+			}
+
+			if ((pattrib->crc_err) || (pattrib->icv_err))
+			{
+#ifdef CONFIG_MP_INCLUDED
+				if (padapter->registrypriv.mp_mode == 1)
+				{
+					if ((check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0))
+					{
+						if (pattrib->crc_err == 1)
+							padapter->mppriv.rx_crcerrpktcount++;
+					}
+				}
+				else
+#endif
+				{
+					DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);
+				}
+				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+			}
+			else
+			{
+				//	Modified by Albert 20101213
+				//	For 8 bytes IP header alignment.
+				if (pattrib->qos)	//	Qos data, wireless lan header length is 26
+				{
+					shift_sz = 6;
+				}
+				else
+				{
+					shift_sz = 0;
+				}
+
+				skb_len = pattrib->pkt_len;
+
+				// for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
+				// modify alloc_sz for recvive crc error packet by thomas 2011-06-02
+				if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
+					//alloc_sz = 1664;	//1664 is 128 alignment.
+					if(skb_len <= 1650)
+						alloc_sz = 1664;
+					else
+						alloc_sz = skb_len + 14;
+				}
+				else {
+					alloc_sz = skb_len;
+					//	6 is for IP header 8 bytes alignment in QoS packet case.
+					//	8 is for skb->data 4 bytes alignment.
+					alloc_sz += 14;
+				}
+
+				pkt_copy = rtw_skb_alloc(alloc_sz);
+
+				if (pkt_copy)
+				{
+					pkt_copy->dev = padapter->pnetdev;
+					precvframe->u.hdr.pkt = pkt_copy;
+					skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
+					skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
+					_rtw_memcpy(pkt_copy->data, (ptr + rx_report_sz + pattrib->shift_sz), skb_len);
+					precvframe->u.hdr.rx_head = pkt_copy->head;
+					precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
+					precvframe->u.hdr.rx_end = skb_end_pointer(pkt_copy);
+				}
+				else
+				{
+					if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
+					{
+						DBG_8192C("%s: alloc_skb fail, drop frag frame\n", __FUNCTION__);
+						rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+						break;
+					}
+
+					precvframe->u.hdr.pkt = rtw_skb_clone(precvbuf->pskb);
+					if(precvframe->u.hdr.pkt)
+					{
+						_pkt	*pkt_clone = precvframe->u.hdr.pkt;
+
+						pkt_clone->data = ptr + rx_report_sz + pattrib->shift_sz;
+						skb_reset_tail_pointer(pkt_clone);
+						precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail
+							= pkt_clone->data;
+						precvframe->u.hdr.rx_end =	pkt_clone->data + skb_len;
+					}
+					else
+					{
+						DBG_8192C("%s: rtw_skb_clone fail\n", __FUNCTION__);
+						rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+						break;
+					}
+				}
+
+				recvframe_put(precvframe, skb_len);
+				//recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);
+
+				if (pHalData->ReceiveConfig & RCR_APPFCS)
+					recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN);
+
+				// move to drv info position
+				ptr += RXDESC_SIZE;
+
+				// update drv info
+				if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) {
+					//rtl8703s_update_bassn(padapter, pdrvinfo);
+					ptr += 4;
+				}
+
+				if (pattrib->pkt_rpt_type == NORMAL_RX) {
+					// skip the rx packet with abnormal length
+					if (pattrib->pkt_len < 14 || pattrib->pkt_len > 8192) {	
+						DBG_8192C("skip abnormal rx packet(%d)\n", pattrib->pkt_len);
+						rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+						break;
+					}
+
+#ifdef CONFIG_CONCURRENT_MODE
+					if (rtw_buddy_adapter_up(padapter))
+					{
+						if (pre_recv_entry(precvframe, precvbuf, ptr) != _SUCCESS) {
+							RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
+								("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
+						}
+					}
+					else
+#endif
+					{
+						if (pattrib->physt)
+							rx_query_phy_status(precvframe, ptr);
+
+						if (rtw_recv_entry(precvframe) != _SUCCESS) {
+							RT_TRACE(_module_rtl871x_recv_c_, _drv_dump_, ("%s: rtw_recv_entry(precvframe) != _SUCCESS\n",__FUNCTION__));
+						}
+					}
+				}
+				else {
+#ifdef CONFIG_C2H_PACKET_EN
+					if (pattrib->pkt_rpt_type == C2H_PACKET) {
+						rtl8703b_c2h_packet_handler(padapter, precvframe->u.hdr.rx_data, pattrib->pkt_len);
+					}
+					else {
+						DBG_8192C("%s: [WARNNING] RX type(%d) not be handled!\n",
+							__FUNCTION__, pattrib->pkt_rpt_type);
+					}
+#endif
+					rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+				}
+			}
+
+			pkt_offset = _RND8(pkt_offset);
+			precvbuf->pdata += pkt_offset;
+			ptr = precvbuf->pdata;
+			precvframe = NULL;
+			pkt_copy = NULL;
+		}
+
+		rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
+	} while (1);
+
+}
+#else
+static void rtl8703bs_recv_tasklet(void *priv)
+{
+	PADAPTER				padapter;
+	PHAL_DATA_TYPE			pHalData;
+	struct recv_priv		*precvpriv;
+	struct recv_buf 		*precvbuf;
+	union recv_frame		*precvframe;
+	struct recv_frame_hdr	*phdr;
+	struct rx_pkt_attrib	*pattrib;
+	u8			*ptr;
+	_pkt		*ppkt;
+	u32 		pkt_offset;
+	_irqL		irql;
+
+
+	padapter = (PADAPTER)priv;
+	pHalData = GET_HAL_DATA(padapter);
+	precvpriv = &padapter->recvpriv;
+
+	do {
+		precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
+		if (NULL == precvbuf) break;
+
+		ptr = precvbuf->pdata;
+
+		while (ptr < precvbuf->ptail)
+		{
+			precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
+			if (precvframe == NULL) {
+				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("rtl8703bs_recv_tasklet: no enough recv frame!\n"));
+				rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
+
+				// The case of can't allocte recvframe should be temporary,
+				// schedule again and hope recvframe is available next time.
+#ifdef PLATFORM_LINUX
+				tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+				return;
+			}
+
+			phdr = &precvframe->u.hdr;
+			pattrib = &phdr->attrib;
+
+			rtl8703b_query_rx_desc_status(precvframe, ptr);
+
+#if 0
+			{
+				int i, len = 64;
+				u8 *pptr = ptr;
+
+				if((*(pptr + RXDESC_SIZE + pattrib->drvinfo_sz) != 0x80) && (*(pptr + RXDESC_SIZE + pattrib->drvinfo_sz) != 0x40))
+				{
+					DBG_871X("##############RxDESC############### \n");
+					for(i=0; i<32;i=i+16)
+						DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(pptr+i),
+						*(pptr+i+1), *(pptr+i+2) ,*(pptr+i+3) ,*(pptr+i+4),*(pptr+i+5), *(pptr+i+6), *(pptr+i+7), *(pptr+i+8), *(pptr+i+9), *(pptr+i+10),
+						 *(pptr+i+11), *(pptr+i+12), *(pptr+i+13), *(pptr+i+14), *(pptr+i+15));
+					
+					if(pattrib->pkt_len < 100)
+						len = pattrib->pkt_len;
+					pptr = ptr + RXDESC_SIZE + pattrib->drvinfo_sz;
+					DBG_871X("##############Len=%d############### \n", pattrib->pkt_len);
+					for(i=0; i<len;i=i+16)
+						DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(pptr+i),
+						*(pptr+i+1), *(pptr+i+2) ,*(pptr+i+3) ,*(pptr+i+4),*(pptr+i+5), *(pptr+i+6), *(pptr+i+7), *(pptr+i+8), *(pptr+i+9), *(pptr+i+10),
+						 *(pptr+i+11), *(pptr+i+12), *(pptr+i+13), *(pptr+i+14), *(pptr+i+15));
+					DBG_871X("############################# \n");
+				}
+			}
+#endif
+
+			// fix Hardware RX data error, drop whole recv_buffer
+			if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err)
+			{
+				DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
+				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+				break;
+			}
+
+			pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->pkt_len;
+#if 0 // reduce check to speed up
+			if ((ptr + pkt_offset) > precvbuf->ptail) {
+				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
+						("%s: next pkt len(%p,%d) exceed ptail(%p)!\n",
+						__FUNCTION__, ptr, pkt_offset, precvbuf->ptail));
+				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+				break;
+			}
+#endif
+
+			if ((pattrib->crc_err) || (pattrib->icv_err))
+			{
+#ifdef CONFIG_MP_INCLUDED
+				if (padapter->registrypriv.mp_mode == 1)
+				{
+					if ((check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0))
+					{
+						if (pattrib->crc_err == 1)
+							padapter->mppriv.rx_crcerrpktcount++;
+					}
+				}
+				else
+#endif
+				{
+					DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);
+				}
+				rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+			}
+			else
+			{
+				ppkt = rtw_skb_clone(precvbuf->pskb);
+				if (ppkt == NULL) {
+					DBG_8192C("%s: no enough memory to allocate SKB!\n", __FUNCTION__);
+					rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+					rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
+
+					// The case of can't allocte skb is serious and may never be recovered,
+					// once bDriverStopped is enable, this task should be stopped.
+					if (padapter->bDriverStopped == _FALSE) {
+#ifdef PLATFORM_LINUX
+						tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+					}
+
+					return;
+				}
+
+				phdr->pkt = ppkt;
+				phdr->len = 0;
+				phdr->rx_head = precvbuf->phead;
+				phdr->rx_data = phdr->rx_tail = precvbuf->pdata;
+				phdr->rx_end = precvbuf->pend;
+				recvframe_put(precvframe, pkt_offset);
+				recvframe_pull(precvframe, RXDESC_SIZE + pattrib->drvinfo_sz);
+				if (pHalData->ReceiveConfig & RCR_APPFCS)
+					recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN);
+
+				// move to drv info position
+				ptr += RXDESC_SIZE;
+
+				// update drv info
+				if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) {
+					//rtl8703s_update_bassn(padapter, pdrvinfo);
+					ptr += 4;
+				}
+
+				if (pattrib->pkt_rpt_type == NORMAL_RX) {
+#ifdef CONFIG_CONCURRENT_MODE
+					if (rtw_buddy_adapter_up(padapter))
+					{
+						if (pre_recv_entry(precvframe, precvbuf, ptr) != _SUCCESS) {
+							RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
+								("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
+						}
+					}
+					else
+#endif
+					{
+						if (pattrib->physt)
+							rx_query_phy_status(precvframe, ptr);
+
+						if (rtw_recv_entry(precvframe) != _SUCCESS)
+						{
+							RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("rtl8703bs_recv_tasklet: rtw_recv_entry(precvframe) != _SUCCESS\n"));
+						}
+					}
+				}
+				else {
+#ifdef CONFIG_C2H_PACKET_EN
+					if (pattrib->pkt_rpt_type == C2H_PACKET) {
+						rtl8703b_c2h_packet_handler(padapter, precvframe->u.hdr.rx_data, pattrib->pkt_len);
+					}
+					else {
+						DBG_8192C("%s: [WARNNING] RX type(%d) not be handled!\n",
+							__FUNCTION__, pattrib->pkt_rpt_type);
+					}
+#endif
+					rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
+				}
+			}
+
+			pkt_offset = _RND8(pkt_offset);
+			precvbuf->pdata += pkt_offset;
+			ptr = precvbuf->pdata;
+		}
+
+		rtw_skb_free(precvbuf->pskb);
+		precvbuf->pskb = NULL;
+		rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
+	} while (1);
+}
+#endif
+
+/*
+ * Initialize recv private variable for hardware dependent
+ * 1. recv buf
+ * 2. recv tasklet
+ *
+ */
+s32 rtl8703bs_init_recv_priv(PADAPTER padapter)
+{
+	s32			res;
+	u32			i, n;
+	struct recv_priv	*precvpriv;
+	struct recv_buf		*precvbuf;
+
+
+	res = _SUCCESS;
+	precvpriv = &padapter->recvpriv;
+
+	//3 1. init recv buffer
+	_rtw_init_queue(&precvpriv->free_recv_buf_queue);
+	_rtw_init_queue(&precvpriv->recv_buf_pending_queue);
+
+	n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
+	precvpriv->pallocated_recv_buf = rtw_zmalloc(n);
+	if (precvpriv->pallocated_recv_buf == NULL) {
+		res = _FAIL;
+		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("alloc recv_buf fail!\n"));
+		goto exit;
+	}
+
+	precvpriv->precv_buf = (u8*)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
+
+	// init each recv buffer
+	precvbuf = (struct recv_buf*)precvpriv->precv_buf;
+	for (i = 0; i < NR_RECVBUFF; i++)
+	{
+		res = initrecvbuf(precvbuf, padapter);
+		if (res == _FAIL)
+			break;
+
+		res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
+		if (res == _FAIL) {
+			freerecvbuf(precvbuf);
+			break;
+		}
+
+#ifdef CONFIG_SDIO_RX_COPY
+		if (precvbuf->pskb == NULL) {
+			SIZE_PTR tmpaddr=0;
+			SIZE_PTR alignment=0;
+
+			precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
+
+			if(precvbuf->pskb)
+			{
+				precvbuf->pskb->dev = padapter->pnetdev;
+
+				tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
+				alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
+				skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
+			}
+
+			if (precvbuf->pskb == NULL) {
+				DBG_871X("%s: alloc_skb fail!\n", __FUNCTION__);
+			}
+		}
+#endif
+
+		rtw_list_insert_tail(&precvbuf->list, &precvpriv->free_recv_buf_queue.queue);
+
+		precvbuf++;
+	}
+	precvpriv->free_recv_buf_queue_cnt = i;
+
+	if (res == _FAIL)
+		goto initbuferror;
+
+	//3 2. init tasklet
+#ifdef PLATFORM_LINUX
+	tasklet_init(&precvpriv->recv_tasklet,
+	     (void(*)(unsigned long))rtl8703bs_recv_tasklet,
+	     (unsigned long)padapter);
+#endif
+
+	goto exit;
+
+initbuferror:
+	precvbuf = (struct recv_buf*)precvpriv->precv_buf;
+	if (precvbuf) {
+		n = precvpriv->free_recv_buf_queue_cnt;
+		precvpriv->free_recv_buf_queue_cnt = 0;
+		for (i = 0; i < n ; i++)
+		{
+			rtw_list_delete(&precvbuf->list);
+			rtw_os_recvbuf_resource_free(padapter, precvbuf);
+			freerecvbuf(precvbuf);
+			precvbuf++;
+		}
+		precvpriv->precv_buf = NULL;
+	}
+
+	if (precvpriv->pallocated_recv_buf) {
+		n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
+		rtw_mfree(precvpriv->pallocated_recv_buf, n);
+		precvpriv->pallocated_recv_buf = NULL;
+	}
+
+exit:
+	return res;
+}
+
+/*
+ * Free recv private variable of hardware dependent
+ * 1. recv buf
+ * 2. recv tasklet
+ *
+ */
+void rtl8703bs_free_recv_priv(PADAPTER padapter)
+{
+	u32			i, n;
+	struct recv_priv	*precvpriv;
+	struct recv_buf		*precvbuf;
+
+
+	precvpriv = &padapter->recvpriv;
+
+	//3 1. kill tasklet
+#ifdef PLATFORM_LINUX
+	tasklet_kill(&precvpriv->recv_tasklet);
+#endif
+
+	//3 2. free all recv buffers
+	precvbuf = (struct recv_buf*)precvpriv->precv_buf;
+	if (precvbuf) {
+		n = NR_RECVBUFF;
+		precvpriv->free_recv_buf_queue_cnt = 0;
+		for (i = 0; i < n ; i++)
+		{
+			rtw_list_delete(&precvbuf->list);
+			rtw_os_recvbuf_resource_free(padapter, precvbuf);
+			freerecvbuf(precvbuf);
+			precvbuf++;
+		}
+		precvpriv->precv_buf = NULL;
+	}
+
+	if (precvpriv->pallocated_recv_buf) {
+		n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
+		rtw_mfree(precvpriv->pallocated_recv_buf, n);
+		precvpriv->pallocated_recv_buf = NULL;
+	}
+}
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_xmit.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_xmit.c
new file mode 100644
index 000000000..66a36217b
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/rtl8703bs_xmit.c
@@ -0,0 +1,769 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *
+ ******************************************************************************/
+#define _RTL8703BS_XMIT_C_
+
+#include <rtl8703b_hal.h>
+
+static u8 rtw_sdio_wait_enough_TxOQT_space(PADAPTER padapter, u8 agg_num)
+{
+	u32 n = 0;
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+	while (pHalData->SdioTxOQTFreeSpace < agg_num) 
+	{
+		if (RTW_CANNOT_RUN(padapter)) {
+			DBG_871X("%s: bSurpriseRemoved or bDriverStopped (wait TxOQT)\n", __func__);
+			return _FALSE;
+		}
+
+		HalQueryTxOQTBufferStatus8703BSdio(padapter);
+		
+		if ((++n % 60) == 0) {
+			if ((n % 300) == 0) {			
+				DBG_871X("%s(%d): QOT free space(%d), agg_num: %d\n",
+ 				__func__, n, pHalData->SdioTxOQTFreeSpace, agg_num);
+			}	
+			rtw_msleep_os(1);
+			//yield();
+		}
+	}
+
+	pHalData->SdioTxOQTFreeSpace -= agg_num;
+	
+	//if (n > 1)
+	//	++priv->pshare->nr_out_of_txoqt_space;
+
+	return _TRUE;
+}
+
+static s32 rtl8703_dequeue_writeport(PADAPTER padapter)
+{
+	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
+	struct xmit_buf *pxmitbuf;
+	u8	PageIdx = 0;
+	u32	deviceId;
+#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
+	u8	bUpdatePageNum = _FALSE;
+#else
+	u32	polling_num = 0;
+#endif
+
+	if (rtw_xmit_ac_blocked(padapter) == _TRUE)
+		pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
+	else
+		pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
+
+	if (pxmitbuf == NULL)
+		return _TRUE;
+
+	deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr);
+
+	// translate fifo addr to queue index
+	switch (deviceId) {
+		case WLAN_TX_HIQ_DEVICE_ID:
+				PageIdx = HI_QUEUE_IDX;
+				break;
+
+		case WLAN_TX_MIQ_DEVICE_ID:
+				PageIdx = MID_QUEUE_IDX;
+				break;
+
+		case WLAN_TX_LOQ_DEVICE_ID:
+				PageIdx = LOW_QUEUE_IDX;
+				break;
+	}
+
+query_free_page:
+	/* check if hardware tx fifo page is enough */
+	if (_FALSE == rtw_hal_sdio_query_tx_freepage(padapter, PageIdx, pxmitbuf->pg_num)) {
+#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
+		if (!bUpdatePageNum) {
+			// Total number of page is NOT available, so update current FIFO status
+			HalQueryTxBufferStatus8703BSdio(padapter);
+			bUpdatePageNum = _TRUE;
+			goto query_free_page;
+		} else {
+			bUpdatePageNum = _FALSE;
+			enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
+			return _TRUE;
+		}
+#else //CONFIG_SDIO_TX_ENABLE_AVAL_INT
+		polling_num++;
+		if ((polling_num % 0x7F) == 0) {//or 80
+			//DBG_871X("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n",
+			//	__func__, polling_num, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]);
+			rtw_msleep_os(1);
+		}
+
+		// Total number of page is NOT available, so update current FIFO status
+		HalQueryTxBufferStatus8703BSdio(padapter);
+		goto query_free_page;
+#endif //CONFIG_SDIO_TX_ENABLE_AVAL_INT
+	}
+
+	if (RTW_CANNOT_RUN(padapter)) {
+		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
+			 ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__));
+		goto free_xmitbuf;
+	}
+
+	if (rtw_sdio_wait_enough_TxOQT_space(padapter, pxmitbuf->agg_num) == _FALSE) 
+	{
+		goto free_xmitbuf;
+	}
+
+#ifdef CONFIG_CHECK_LEAVE_LPS
+	traffic_check_for_leave_lps(padapter, _TRUE, pxmitbuf->agg_num);
+#endif 
+
+	rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf);
+
+	rtw_hal_sdio_update_tx_freepage(padapter, PageIdx, pxmitbuf->pg_num);
+
+free_xmitbuf:
+	//rtw_free_xmitframe(pxmitpriv, pframe);
+	//pxmitbuf->priv_data = NULL;
+	rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+
+#if 0 // improve TX/RX throughput balance
+{
+	PSDIO_DATA psdio;
+	struct sdio_func *func;
+	static u8 i = 0;
+	u32 sdio_hisr;
+	u8 j;
+
+	psdio = &adapter_to_dvobj(padapter)->intf_data;
+	func = psdio->func;
+
+	if (i == 2)
+	{
+		j = 0;
+		while (j < 10)
+		{
+			sdio_hisr = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR);
+			sdio_hisr &= GET_HAL_DATA(padapter)->sdio_himr;
+			if (sdio_hisr & SDIO_HISR_RX_REQUEST)
+			{
+				sdio_claim_host(func);
+				sd_int_hdl(GET_PRIMARY_ADAPTER(padapter));
+				sdio_release_host(func);
+			}
+			else
+			{
+				break;
+			}
+			j++;
+		}
+		i = 0;
+	}
+	else
+	{
+		i++;
+	}
+}
+#endif
+
+#ifdef CONFIG_SDIO_TX_TASKLET
+	tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
+#endif
+
+	return _FAIL;
+}
+
+/*
+ * Description
+ *	Transmit xmitbuf to hardware tx fifo
+ *
+ * Return
+ *	_SUCCESS	ok
+ *	_FAIL		something error
+ */
+s32 rtl8703bs_xmit_buf_handler(PADAPTER padapter)
+{
+	struct xmit_priv *pxmitpriv;
+	u8	queue_empty, queue_pending;
+	s32	ret;
+
+
+	pxmitpriv = &padapter->xmitpriv;
+
+	ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
+	if (_FAIL == ret) {
+		DBG_871X_LEVEL(_drv_emerg_, "%s: down SdioXmitBufSema fail!\n", __FUNCTION__);
+		return _FAIL;
+	}
+
+	if (RTW_CANNOT_RUN(padapter)) {
+		RT_TRACE(_module_hal_xmit_c_, _drv_err_
+				, ("%s: bDriverStopped(%s) bSurpriseRemoved(%s)!\n"
+				, __func__
+				, rtw_is_drv_stopped(padapter)?"True":"False"
+				, rtw_is_surprise_removed(padapter)?"True":"False"));
+		return _FAIL;
+	}
+
+	queue_pending = check_pending_xmitbuf(pxmitpriv);
+
+#ifdef CONFIG_CONCURRENT_MODE
+	if(rtw_buddy_adapter_up(padapter))
+		queue_pending |= check_pending_xmitbuf(&padapter->pbuddy_adapter->xmitpriv);
+#endif
+
+	if(queue_pending == _FALSE)
+		return _SUCCESS;
+
+#ifdef CONFIG_LPS_LCLK
+	ret = rtw_register_tx_alive(padapter);
+	if (ret != _SUCCESS) {
+		return _SUCCESS;
+	}
+#endif
+
+	do {
+		queue_empty = rtl8703_dequeue_writeport(padapter);
+//	dump secondary adapter xmitbuf
+#ifdef CONFIG_CONCURRENT_MODE
+		if(rtw_buddy_adapter_up(padapter))
+			queue_empty &= rtl8703_dequeue_writeport(padapter->pbuddy_adapter);
+#endif
+	} while ( !queue_empty);
+
+#ifdef CONFIG_LPS_LCLK
+	rtw_unregister_tx_alive(padapter);
+#endif
+
+	return _SUCCESS;
+}
+
+/*
+ * Description:
+ *	Aggregation packets and send to hardware
+ *
+ * Return:
+ *	0	Success
+ *	-1	Hardware resource(TX FIFO) not ready
+ *	-2	Software resource(xmitbuf) not ready
+ */
+static s32 xmit_xmitframes(PADAPTER padapter, struct xmit_priv *pxmitpriv)
+{
+	s32 err, ret;
+	u32 k=0;
+	struct hw_xmit *hwxmits, *phwxmit;
+	u8 no_res, idx, hwentry;
+	_irqL irql;
+	struct tx_servq *ptxservq;
+	_list *sta_plist, *sta_phead, *frame_plist, *frame_phead;
+	struct xmit_frame *pxmitframe;
+	_queue *pframe_queue;
+	struct xmit_buf *pxmitbuf;
+	u32 txlen, max_xmit_len;
+	u8 txdesc_size = TXDESC_SIZE;
+	int inx[4];
+	u8 pre_qsel=0xFF,next_qsel=0xFF;
+	u8 single_sta_in_queue = _FALSE;
+
+	err = 0;
+	no_res = _FALSE;
+	hwxmits = pxmitpriv->hwxmits;
+	hwentry = pxmitpriv->hwxmit_entry;
+	ptxservq = NULL;
+	pxmitframe = NULL;
+	pframe_queue = NULL;
+	pxmitbuf = NULL;
+
+	if (padapter->registrypriv.wifi_spec == 1) {
+		for(idx=0; idx<4; idx++)
+			inx[idx] = pxmitpriv->wmm_para_seq[idx];
+	} else {
+		inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
+	}
+
+	// 0(VO), 1(VI), 2(BE), 3(BK)
+	for (idx = 0; idx < hwentry; idx++)
+	{
+		phwxmit = hwxmits + inx[idx];
+	
+		if((check_pending_xmitbuf(pxmitpriv) == _TRUE) && (padapter->mlmepriv.LinkDetectInfo.bHigherBusyTxTraffic == _TRUE)) {
+			if ((phwxmit->accnt > 0) && (phwxmit->accnt < 5)) {
+				err = -2;
+				break;
+			}
+		}
+
+		max_xmit_len = rtw_hal_get_sdio_tx_max_length(padapter, inx[idx]);
+
+		_enter_critical_bh(&pxmitpriv->lock, &irql);
+		
+		sta_phead = get_list_head(phwxmit->sta_queue);
+		sta_plist = get_next(sta_phead);
+		//because stop_sta_xmit may delete sta_plist at any time
+		//so we should add lock here, or while loop can not exit
+
+		single_sta_in_queue = rtw_end_of_queue_search(sta_phead, get_next(sta_plist));
+
+		while (rtw_end_of_queue_search(sta_phead, sta_plist) == _FALSE)
+		{
+			ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending);
+			sta_plist = get_next(sta_plist);
+
+#ifdef DBG_XMIT_BUF
+			DBG_871X("%s idx:%d hwxmit_pkt_num:%d ptxservq_pkt_num:%d\n", __func__, idx, phwxmit->accnt, ptxservq->qcnt);
+			DBG_871X("%s free_xmit_extbuf_cnt=%d free_xmitbuf_cnt=%d free_xmitframe_cnt=%d \n",
+				       	__func__, pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xmitbuf_cnt,
+					pxmitpriv->free_xmitframe_cnt);
+#endif
+			pframe_queue = &ptxservq->sta_pending;
+
+			frame_phead = get_list_head(pframe_queue);
+
+			while (rtw_is_list_empty(frame_phead) == _FALSE)
+			{
+				frame_plist = get_next(frame_phead);
+				pxmitframe = LIST_CONTAINOR(frame_plist, struct xmit_frame, list);
+				
+				// check xmit_buf size enough or not
+				txlen = txdesc_size + rtw_wlan_pkt_size(pxmitframe);
+				next_qsel = pxmitframe->attrib.qsel;
+				if ((NULL == pxmitbuf) ||
+					((_RND(pxmitbuf->len, 8) + txlen) > max_xmit_len)
+					|| (k >= (rtw_hal_sdio_max_txoqt_free_space(padapter)-1))
+					|| ((k!=0) && (_FAIL == rtw_hal_busagg_qsel_check(padapter,pre_qsel,next_qsel)))
+				)
+				{
+					if (pxmitbuf)
+					{
+						//pxmitbuf->priv_data will be NULL, and will crash here
+						if (pxmitbuf->len > 0 && pxmitbuf->priv_data)
+						{
+							struct xmit_frame *pframe;
+							pframe = (struct xmit_frame*)pxmitbuf->priv_data;
+							pframe->agg_num = k;
+							pxmitbuf->agg_num = k;
+							rtl8703b_update_txdesc(pframe, pframe->buf_addr);
+							rtw_free_xmitframe(pxmitpriv, pframe);
+							pxmitbuf->priv_data = NULL;
+							enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
+							//can not yield under lock
+
+							//rtw_yield_os();
+							if (single_sta_in_queue == _FALSE) {
+								/* break the loop in case there is more than one sta in this ac queue */
+								pxmitbuf = NULL;
+								err = -3;
+								break;
+							}
+						} else {
+							rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+						}
+					}
+
+					pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
+					if (pxmitbuf == NULL) {
+#ifdef DBG_XMIT_BUF
+						DBG_871X_LEVEL(_drv_err_, "%s: xmit_buf is not enough!\n", __FUNCTION__);
+#endif
+						err = -2;
+#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
+	#ifdef CONFIG_CONCURRENT_MODE
+						if (padapter->adapter_type > PRIMARY_ADAPTER)
+							_rtw_up_sema(&(padapter->pbuddy_adapter->xmitpriv.xmit_sema));
+						else
+	#endif
+							_rtw_up_sema(&(pxmitpriv->xmit_sema));
+#endif
+						break;
+					}
+					k = 0;
+				}
+
+				// ok to send, remove frame from queue
+#ifdef CONFIG_AP_MODE
+				if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
+					if ((pxmitframe->attrib.psta->state & WIFI_SLEEP_STATE) &&
+						(pxmitframe->attrib.triggered == 0)) {
+						DBG_871X("%s: one not triggered pkt in queue when this STA sleep,"
+								" break and goto next sta\n", __func__);
+						break;
+					}
+				}
+#endif
+				rtw_list_delete(&pxmitframe->list);
+				ptxservq->qcnt--;
+				phwxmit->accnt--;
+
+				if (k == 0) {
+					pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
+					pxmitbuf->priv_data = (u8*)pxmitframe;
+				}
+
+				// coalesce the xmitframe to xmitbuf
+				pxmitframe->pxmitbuf = pxmitbuf;
+				pxmitframe->buf_addr = pxmitbuf->ptail;
+
+				ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
+				if (ret == _FAIL) {
+					DBG_871X_LEVEL(_drv_err_, "%s: coalesce FAIL!", __FUNCTION__);
+					// Todo: error handler
+				} else {
+					k++;
+					if (k != 1)
+						rtl8703b_update_txdesc(pxmitframe, pxmitframe->buf_addr);
+					rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz);
+					pre_qsel = pxmitframe->attrib.qsel;
+					txlen = txdesc_size + pxmitframe->attrib.last_txcmdsz;
+					pxmitframe->pg_num = (txlen + 127)/128;
+					pxmitbuf->pg_num += (txlen + 127)/128;
+				    //if (k != 1)
+					//	((struct xmit_frame*)pxmitbuf->priv_data)->pg_num += pxmitframe->pg_num;
+					pxmitbuf->ptail += _RND(txlen, 8); // round to 8 bytes alignment
+					pxmitbuf->len = _RND(pxmitbuf->len, 8) + txlen;
+				}
+
+				if (k != 1)
+					rtw_free_xmitframe(pxmitpriv, pxmitframe);
+				pxmitframe = NULL;
+			}
+
+			if (_rtw_queue_empty(pframe_queue) == _TRUE)
+				rtw_list_delete(&ptxservq->tx_pending);
+			else if (err == -3) {
+				/* Re-arrange the order of stations in this ac queue to balance the service for these stations */
+				rtw_list_delete(&ptxservq->tx_pending);
+				rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmit->sta_queue));
+			}
+
+			if (err) break;
+		}
+		_exit_critical_bh(&pxmitpriv->lock, &irql);
+		
+		// dump xmit_buf to hw tx fifo
+		if (pxmitbuf)
+		{
+			RT_TRACE(_module_hal_xmit_c_, _drv_info_, ("pxmitbuf->len=%d enqueue\n",pxmitbuf->len));
+
+			if (pxmitbuf->len > 0) {
+				struct xmit_frame *pframe;
+				pframe = (struct xmit_frame*)pxmitbuf->priv_data;
+				pframe->agg_num = k;
+				pxmitbuf->agg_num = k;
+				rtl8703b_update_txdesc(pframe, pframe->buf_addr);
+				rtw_free_xmitframe(pxmitpriv, pframe);
+				pxmitbuf->priv_data = NULL;
+				enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
+				rtw_yield_os();
+			}
+			else
+				rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+			pxmitbuf = NULL;
+		}
+		
+		if (err == -2) 
+			break;
+	}
+
+	return err;
+}
+
+/*
+ * Description
+ *	Transmit xmitframe from queue
+ *
+ * Return
+ *	_SUCCESS	ok
+ *	_FAIL		something error
+ */
+s32 rtl8703bs_xmit_handler(PADAPTER padapter)
+{
+	struct xmit_priv *pxmitpriv;
+	s32 ret;
+	_irqL irql;
+
+
+	pxmitpriv = &padapter->xmitpriv;
+
+wait:
+	ret = _rtw_down_sema(&pxmitpriv->SdioXmitSema);
+	if (_FAIL == ret) {
+		DBG_871X_LEVEL(_drv_emerg_, "%s: down sema fail!\n", __FUNCTION__);
+		return _FAIL;
+	}
+
+next:
+	if (RTW_CANNOT_RUN(padapter)) {
+		RT_TRACE(_module_hal_xmit_c_, _drv_notice_
+				, ("%s: bDriverStopped(%s) bSurpriseRemoved(%s)\n"
+				, __func__
+				, rtw_is_drv_stopped(padapter)?"True":"False"
+				, rtw_is_surprise_removed(padapter)?"True":"False"));
+		return _FAIL;
+	}
+
+	_enter_critical_bh(&pxmitpriv->lock, &irql);
+	ret = rtw_txframes_pending(padapter);
+	_exit_critical_bh(&pxmitpriv->lock, &irql);
+	if (ret == 0) {
+		return _SUCCESS;
+	}
+
+	// dequeue frame and write to hardware
+
+	ret = xmit_xmitframes(padapter, pxmitpriv);
+	if (ret == -2) {
+		//here sleep 1ms will cause big TP loss of TX
+		//from 50+ to 40+
+		if(padapter->registrypriv.wifi_spec)
+			rtw_msleep_os(1);
+		else
+#ifdef CONFIG_REDUCE_TX_CPU_LOADING 
+			rtw_msleep_os(1);
+#else
+			rtw_usleep_os(50);
+#endif
+		goto next;
+	}
+
+	_enter_critical_bh(&pxmitpriv->lock, &irql);
+	ret = rtw_txframes_pending(padapter);
+	_exit_critical_bh(&pxmitpriv->lock, &irql);
+	if (ret == 1) {
+#ifdef CONFIG_REDUCE_TX_CPU_LOADING 
+		rtw_msleep_os(1);
+#endif
+		goto next;
+	}
+
+	return _SUCCESS;
+}
+
+thread_return rtl8703bs_xmit_thread(thread_context context)
+{
+	s32 ret;
+	PADAPTER padapter;
+	struct xmit_priv *pxmitpriv;
+	u8 thread_name[20] = "RTWHALXT";
+
+
+	ret = _SUCCESS;
+	padapter = (PADAPTER)context;
+	pxmitpriv = &padapter->xmitpriv;
+
+	rtw_sprintf(thread_name, 20, "%s-"ADPT_FMT, thread_name, ADPT_ARG(padapter));
+	thread_enter(thread_name);
+
+	DBG_871X("start "FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+
+	// For now, no one would down sema to check thread is running,
+	// so mark this temporary, Lucas@20130820
+//	_rtw_up_sema(&pxmitpriv->SdioXmitTerminateSema);
+
+	do {
+		ret = rtl8703bs_xmit_handler(padapter);
+		if (signal_pending(current)) {
+			flush_signals(current);
+		}
+	} while (_SUCCESS == ret);
+
+	_rtw_up_sema(&pxmitpriv->SdioXmitTerminateSema);
+
+	RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("-%s\n", __FUNCTION__));
+
+	thread_exit();
+}
+
+s32 rtl8703bs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe)
+{
+	s32 ret = _SUCCESS;
+	struct pkt_attrib *pattrib;
+	struct xmit_buf *pxmitbuf;
+	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
+	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
+	u8 *pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+	u8 txdesc_size = TXDESC_SIZE;
+
+	RT_TRACE(_module_hal_xmit_c_, _drv_info_, ("+%s\n", __FUNCTION__));
+
+	pattrib = &pmgntframe->attrib;
+	pxmitbuf = pmgntframe->pxmitbuf;
+
+	rtl8703b_update_txdesc(pmgntframe, pmgntframe->buf_addr);
+
+	pxmitbuf->len = txdesc_size + pattrib->last_txcmdsz;
+	//pmgntframe->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size
+	pxmitbuf->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size
+	pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len;
+	pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe);
+
+	rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz);
+
+	rtw_free_xmitframe(pxmitpriv, pmgntframe);
+
+	pxmitbuf->priv_data = NULL;
+
+	if(GetFrameSubType(pframe)==WIFI_BEACON) //dump beacon directly
+	{
+		ret = rtw_write_port(padapter, pdvobjpriv->Queue2Pipe[pxmitbuf->ff_hwaddr], pxmitbuf->len, (u8 *)pxmitbuf);
+		if (ret != _SUCCESS)
+			rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
+
+		rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+	}
+	else
+	{
+		enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
+	}
+
+	return ret;
+}
+
+/*
+ * Description:
+ *	Handle xmitframe(packet) come from rtw_xmit()
+ *
+ * Return:
+ *	_TRUE	dump packet directly ok
+ *	_FALSE	enqueue, temporary can't transmit packets to hardware
+ */
+s32 rtl8703bs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe)
+{
+	struct xmit_priv *pxmitpriv;
+	_irqL irql;
+	s32 err;
+
+
+	pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
+	pxmitpriv = &padapter->xmitpriv;
+
+#ifdef CONFIG_80211N_HT
+	if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
+		(pxmitframe->attrib.ether_type != 0x0806) &&
+		(pxmitframe->attrib.ether_type != 0x888e) &&
+		(pxmitframe->attrib.dhcp_pkt != 1))
+	{
+		if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
+			rtw_issue_addbareq_cmd(padapter, pxmitframe);
+	}
+#endif
+
+	_enter_critical_bh(&pxmitpriv->lock, &irql);
+	err = rtw_xmitframe_enqueue(padapter, pxmitframe);
+	_exit_critical_bh(&pxmitpriv->lock, &irql);
+	if (err != _SUCCESS) {
+		RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("rtl8703bs_hal_xmit: enqueue xmitframe fail\n"));
+		rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+		pxmitpriv->tx_drop++;
+		return _TRUE;
+	}
+
+	_rtw_up_sema(&pxmitpriv->SdioXmitSema);
+
+	return _FALSE;
+}
+
+s32	rtl8703bs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+	struct xmit_priv 	*pxmitpriv = &padapter->xmitpriv;
+	s32 err;
+	
+	if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS) 
+	{
+		rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+		pxmitpriv->tx_drop++;					
+	}
+	else
+	{
+#ifdef CONFIG_SDIO_TX_TASKLET
+		tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);					
+#else
+		_rtw_up_sema(&pxmitpriv->SdioXmitSema);
+#endif
+	}
+	
+	return err;
+	
+}
+
+/*
+ * Return
+ *	_SUCCESS	start thread ok
+ *	_FAIL		start thread fail
+ *
+ */
+s32 rtl8703bs_init_xmit_priv(PADAPTER padapter)
+{
+	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
+	PHAL_DATA_TYPE phal;
+
+
+	phal = GET_HAL_DATA(padapter);
+
+	_rtw_spinlock_init(&phal->SdioTxFIFOFreePageLock);
+	_rtw_init_sema(&xmitpriv->SdioXmitSema, 0);
+	_rtw_init_sema(&xmitpriv->SdioXmitTerminateSema, 0);
+
+	return _SUCCESS;
+}
+
+void rtl8703bs_free_xmit_priv(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE phal;
+	struct xmit_priv *pxmitpriv;
+	struct xmit_buf *pxmitbuf;
+	_queue *pqueue;
+	_list *plist, *phead;
+	_list tmplist;
+	_irqL irql;
+
+
+	phal = GET_HAL_DATA(padapter);
+	pxmitpriv = &padapter->xmitpriv;
+	pqueue = &pxmitpriv->pending_xmitbuf_queue;
+	phead = get_list_head(pqueue);
+	_rtw_init_listhead(&tmplist);
+
+	_enter_critical_bh(&pqueue->lock, &irql);
+	if (_rtw_queue_empty(pqueue) == _FALSE)
+	{
+		// Insert tmplist to end of queue, and delete phead
+		// then tmplist become head of queue.
+		rtw_list_insert_tail(&tmplist, phead);
+		rtw_list_delete(phead);
+	}
+	_exit_critical_bh(&pqueue->lock, &irql);
+
+	phead = &tmplist;
+	while (rtw_is_list_empty(phead) == _FALSE)
+	{
+		plist = get_next(phead);
+		rtw_list_delete(plist);
+
+		pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
+		rtw_free_xmitframe(pxmitpriv, (struct xmit_frame*)pxmitbuf->priv_data);
+		pxmitbuf->priv_data = NULL;
+		rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+	}
+
+	_rtw_spinlock_free(&phal->SdioTxFIFOFreePageLock);
+}
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/sdio_halinit.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/sdio_halinit.c
new file mode 100644
index 000000000..0abd78d83
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/sdio_halinit.c
@@ -0,0 +1,2021 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *
+ ******************************************************************************/
+#define _SDIO_HALINIT_C_
+
+#include <rtl8703b_hal.h>
+#include "hal_com_h2c.h"
+
+/*
+ * Description:
+ *	Call power on sequence to enable card
+ *
+ * Return:
+ *	_SUCCESS	enable success
+ *	_FAIL		enable fail
+ */
+static u8 CardEnable(PADAPTER padapter)
+{
+	u8 bMacPwrCtrlOn;
+	u8 ret = _FAIL;
+
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if (bMacPwrCtrlOn == _FALSE)
+	{
+		// RSV_CTRL 0x1C[7:0] = 0x00
+		// unlock ISO/CLK/Power control register
+		rtw_write8(padapter, REG_RSV_CTRL, 0x0);
+
+		ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8703B_card_enable_flow);
+		if (ret == _SUCCESS) {
+			u8 bMacPwrCtrlOn = _TRUE;
+			rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+		}
+	} else
+		ret = _SUCCESS;
+
+	return ret;
+}
+
+/*
+ * Description:
+ *	Call this function to make sure power on successfully
+ *
+ * Return:
+ *	_SUCCESS	enable success
+ *	_FAIL	enable fail
+ */
+static int PowerOnCheck(PADAPTER padapter)
+{
+	u32	val_offset0, val_offset1, val_offset2, val_offset3;
+	u32 val_mix = 0;
+	u32 res = 0;
+	u8	ret = _FAIL;
+	int index = 0;
+
+	val_offset0 = rtw_read8(padapter, REG_CR);
+	val_offset1 = rtw_read8(padapter, REG_CR+1);
+	val_offset2 = rtw_read8(padapter, REG_CR+2);
+	val_offset3 = rtw_read8(padapter, REG_CR+3);
+
+	if (val_offset0 == 0xEA || val_offset1 == 0xEA ||
+			val_offset2 == 0xEA || val_offset3 ==0xEA) {
+		DBG_871X("%s: power on fail, do Power on again\n", __func__);
+		return ret;
+	}
+
+	val_mix = val_offset3 << 24 | val_mix;
+	val_mix = val_offset2 << 16 | val_mix;
+	val_mix = val_offset1 << 8 | val_mix;
+	val_mix = val_offset0 | val_mix;
+
+	res = rtw_read32(padapter, REG_CR);
+
+	DBG_871X("%s: val_mix:0x%08x, res:0x%08x\n", __func__, val_mix, res);
+
+	while(index < 100) {
+		if (res == val_mix) {
+			DBG_871X("%s: 0x100 the result of cmd52 and cmd53 is the same.\n", __func__);
+			ret = _SUCCESS;
+			break;
+		} else {
+			DBG_871X("%s: 0x100 cmd52 and cmd53 is not the same(index:%d).\n", __func__, index);
+			res = rtw_read32(padapter, REG_CR);
+			index ++;
+			ret = _FAIL;
+		}
+	}
+
+	if (ret) {
+		index = 0;
+		while(index < 100) {
+			rtw_write32(padapter, 0x1B8, 0x12345678);
+			res = rtw_read32(padapter, 0x1B8);
+			if (res == 0x12345678) {
+				DBG_871X("%s: 0x1B8 test Pass.\n", __func__);
+				ret = _SUCCESS;
+				break;
+			} else {
+				index ++;
+				DBG_871X("%s: 0x1B8 test Fail(index: %d).\n", __func__, index);
+				ret = _FAIL;
+			}
+		}
+	} else {
+		DBG_871X("%s: fail at cmd52, cmd53.\n", __func__);
+	}
+
+	if (ret == _FAIL) {
+		DBG_871X_LEVEL(_drv_err_, "Dump MAC Page0 register:\n");
+		/* Dump Page0 for check cystal*/
+		for (index = 0 ; index < 0xff ; index++) {
+			if(index%16==0)
+				printk("0x%02x ",index);
+
+			printk("%02x ", rtw_read8(padapter, index)); 
+
+			if(index%16==15)
+				printk("\n");
+			else if(index%8==7)
+				printk("\t");
+		}
+		printk("\n");
+	}
+
+	return ret;
+}
+
+//static
+u32 _InitPowerOn_8703BS(PADAPTER padapter)
+{
+	u8 value8;
+	u16 value16;
+	u32 value32;
+	u8 ret;
+	u8 pwron_chk_cnt=0;
+//	u8 bMacPwrCtrlOn;
+
+_init_power_on:
+
+#if 1
+	// all of these MUST be configured before power on
+#ifdef CONFIG_XTAL_26M
+	// Config PLL Reference CLK,
+	// Change crystal to 26M, APLL_FREF_SEL = 4b'0101
+	// APLL_FREF_SEL[0]=1b'1
+	value8 = rtw_read8(padapter, REG_AFE_PLL_CTRL);
+	value8 |= BIT(2);
+	rtw_write8(padapter, REG_AFE_PLL_CTRL, value8);
+	// APLL_FREF_SEL[2:1]=2b'10
+	value8 = rtw_read8(padapter, REG_AFE_CTRL_4_8703B+1);
+	value8 &= ~(BIT(1)|BIT(0));
+	value8 |= BIT(1);
+	rtw_write16(padapter, REG_AFE_CTRL_4_8703B+1, value8);
+	// APLL_FREF_SEL[3]=1b'0
+	value8 = rtw_read8(padapter, REG_AFE_CTRL_4_8703B);
+	value8 &= ~BIT(7);
+	rtw_write16(padapter, REG_AFE_CTRL_4_8703B, value8);
+#endif // CONFIG_XTAL_26M
+
+#ifdef CONFIG_EXT_CLK
+	// Use external crystal(XTAL)
+	value8 = rtw_read8(padapter, REG_PAD_CTRL1_8703B+2);
+	value8 |=  BIT(7);
+	rtw_write8(padapter, REG_PAD_CTRL1_8703B+2, value8);
+
+	// CLK_REQ High active or Low Active
+	// Request GPIO polarity:
+	// 0: low active
+	// 1: high active
+	value8 = rtw_read8(padapter, REG_MULTI_FUNC_CTRL+1);
+	value8 |= BIT(5);
+	rtw_write8(padapter, REG_MULTI_FUNC_CTRL+1, value8);
+#endif // CONFIG_EXT_CLK
+#endif // all of these MUST be configured before power on
+
+	// only cmd52 can be used before power on(card enable)
+	ret = CardEnable(padapter);
+	if (ret == _FALSE) {
+		RT_TRACE(_module_hci_hal_init_c_, _drv_emerg_,
+				("%s: run power on flow fail\n", __FUNCTION__));
+		return _FAIL;
+	}
+
+	// Radio-Off Pin Trigger
+	value8 = rtw_read8(padapter, REG_GPIO_INTM+1);
+	value8 |= BIT(1); // Enable falling edge triggering interrupt
+	rtw_write8(padapter, REG_GPIO_INTM+1, value8);
+	value8 = rtw_read8(padapter, REG_GPIO_IO_SEL_2+1);
+	value8 |= BIT(1);
+	rtw_write8(padapter, REG_GPIO_IO_SEL_2+1, value8);
+
+	// Enable power down and GPIO interrupt
+	value16 = rtw_read16(padapter, REG_APS_FSMCO);
+	value16 |= EnPDN; // Enable HW power down and RF on
+	rtw_write16(padapter, REG_APS_FSMCO, value16);
+
+	// Enable CMD53 R/W Operation
+//	bMacPwrCtrlOn = _TRUE;
+//	rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+
+	rtw_write8(padapter, REG_CR, 0x00);
+	// Enable MAC DMA/WMAC/SCHEDULE/SEC block
+	value16 = rtw_read16(padapter, REG_CR);
+	value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
+				| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
+	rtw_write16(padapter, REG_CR, value16);
+
+
+	//PowerOnCheck()
+	ret = PowerOnCheck(padapter);
+	pwron_chk_cnt++;	
+	if (_FAIL == ret ) {	
+		if (pwron_chk_cnt > 1) {
+			DBG_871X("Failed to init Power On!\n");
+			return _FAIL;
+		}
+		DBG_871X("Power on Fail! do it again\n");
+		goto _init_power_on;
+	}
+
+#ifdef CONFIG_BT_COEXIST
+	rtw_btcoex_PowerOnSetting(padapter);
+
+	// external switch to S1
+	// 0x38[11] = 0x1
+	// 0x4c[23] = 0x1
+	// 0x64[0] = 0
+	value16 = rtw_read16(padapter, REG_PWR_DATA);
+	// Switch the control of EESK, EECS to RFC for DPDT or Antenna switch
+	value16 |= BIT(11); // BIT_EEPRPAD_RFE_CTRL_EN
+	rtw_write16(padapter, REG_PWR_DATA, value16);
+//	DBG_8192C("%s: REG_PWR_DATA(0x%x)=0x%04X\n", __FUNCTION__, REG_PWR_DATA, rtw_read16(padapter, REG_PWR_DATA));
+
+	value32 = rtw_read32(padapter, REG_LEDCFG0);
+	value32 |= BIT(23); // DPDT_SEL_EN, 1 for SW control
+	rtw_write32(padapter, REG_LEDCFG0, value32);
+//	DBG_8192C("%s: REG_LEDCFG0(0x%x)=0x%08X\n", __FUNCTION__, REG_LEDCFG0, rtw_read32(padapter, REG_LEDCFG0));
+
+	value8 = rtw_read8(padapter, REG_PAD_CTRL1_8703B);
+	value8 &= ~BIT(0); // BIT_SW_DPDT_SEL_DATA, DPDT_SEL default configuration
+	rtw_write8(padapter, REG_PAD_CTRL1_8703B, value8);
+//	DBG_8192C("%s: REG_PAD_CTRL1(0x%x)=0x%02X\n", __FUNCTION__, REG_PAD_CTRL1_8703B, rtw_read8(padapter, REG_PAD_CTRL1_8703B));
+#endif // CONFIG_BT_COEXIST
+
+	return _SUCCESS;
+}
+
+//Tx Page FIFO threshold
+static void _init_available_page_threshold(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ)
+{
+	u16	HQ_threshold, NQ_threshold, LQ_threshold;
+
+	HQ_threshold = (numPubQ + numHQ + 1) >> 1;
+	HQ_threshold |= (HQ_threshold<<8);
+
+	NQ_threshold = (numPubQ + numNQ + 1) >> 1;
+	NQ_threshold |= (NQ_threshold<<8);
+
+	LQ_threshold = (numPubQ + numLQ + 1) >> 1;
+	LQ_threshold |= (LQ_threshold<<8);
+
+	rtw_write16(padapter, 0x218, HQ_threshold);
+	rtw_write16(padapter, 0x21A, NQ_threshold);
+	rtw_write16(padapter, 0x21C, LQ_threshold);
+	DBG_8192C("%s(): Enable Tx FIFO Page Threshold H:0x%x,N:0x%x,L:0x%x\n", __FUNCTION__, HQ_threshold, NQ_threshold, LQ_threshold);
+}
+
+static void _InitQueueReservedPage(PADAPTER padapter)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(padapter);
+	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
+	u32			outEPNum	= (u32)pHalData->OutEpNumber;
+	u32			numHQ		= 0;
+	u32			numLQ		= 0;
+	u32			numNQ		= 0;
+	u32			numPubQ;
+	u32			value32;
+	u8			value8;
+	BOOLEAN			bWiFiConfig	= pregistrypriv->wifi_spec;
+
+	if (pHalData->OutEpQueueSel & TX_SELE_HQ)
+	{
+		numHQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_HPQ_8703B : NORMAL_PAGE_NUM_HPQ_8703B;
+	}
+
+	if (pHalData->OutEpQueueSel & TX_SELE_LQ)
+	{
+		numLQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_LPQ_8703B : NORMAL_PAGE_NUM_LPQ_8703B;
+	}
+
+	// NOTE: This step shall be proceed before writting REG_RQPN.
+	if (pHalData->OutEpQueueSel & TX_SELE_NQ) {
+		numNQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_NPQ_8703B : NORMAL_PAGE_NUM_NPQ_8703B;
+	}
+
+	numPubQ = TX_TOTAL_PAGE_NUMBER_8703B - numHQ - numLQ - numNQ;
+
+	value8 = (u8)_NPQ(numNQ);
+	rtw_write8(padapter, REG_RQPN_NPQ, value8);
+
+	// TX DMA
+	value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
+	rtw_write32(padapter, REG_RQPN, value32);
+
+	rtw_hal_set_sdio_tx_max_length(padapter, numHQ, numNQ, numLQ, numPubQ);
+
+#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
+	_init_available_page_threshold(padapter, numHQ, numNQ, numLQ, numPubQ);
+#endif
+}
+
+static void _InitTxBufferBoundary(PADAPTER padapter)
+{
+	struct registry_priv *pregistrypriv = &padapter->registrypriv;
+#ifdef CONFIG_CONCURRENT_MODE
+	u8 val8;
+#endif // CONFIG_CONCURRENT_MODE
+
+	//u16	txdmactrl;
+	u8	txpktbuf_bndy;
+
+	if (!pregistrypriv->wifi_spec) {
+		txpktbuf_bndy = TX_PAGE_BOUNDARY_8703B;
+	} else {
+		//for WMM
+		txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY_8703B;
+	}
+
+	rtw_write8(padapter, REG_TXPKTBUF_BCNQ_BDNY_8703B, txpktbuf_bndy);
+	rtw_write8(padapter, REG_TXPKTBUF_MGQ_BDNY_8703B, txpktbuf_bndy);
+	rtw_write8(padapter, REG_TXPKTBUF_WMAC_LBK_BF_HD_8703B, txpktbuf_bndy);
+	rtw_write8(padapter, REG_TRXFF_BNDY, txpktbuf_bndy);
+	rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
+
+#ifdef CONFIG_CONCURRENT_MODE
+	val8 = txpktbuf_bndy + BCNQ_PAGE_NUM_8703B + WOWLAN_PAGE_NUM_8703B;
+	rtw_write8(padapter, REG_BCNQ1_BDNY, val8);
+	rtw_write8(padapter, REG_DWBCN1_CTRL_8703B+1, val8); // BCN1_HEAD
+
+	val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8703B+2);
+	val8 |= BIT(1); // BIT1- BIT_SW_BCN_SEL_EN
+	rtw_write8(padapter, REG_DWBCN1_CTRL_8703B+2, val8);
+#endif // CONFIG_CONCURRENT_MODE
+}
+
+static VOID
+_InitNormalChipRegPriority(
+	IN	PADAPTER	Adapter,
+	IN	u16		beQ,
+	IN	u16		bkQ,
+	IN	u16		viQ,
+	IN	u16		voQ,
+	IN	u16		mgtQ,
+	IN	u16		hiQ
+	)
+{
+	u16 value16		= (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+
+	value16 |=	_TXDMA_BEQ_MAP(beQ) 	| _TXDMA_BKQ_MAP(bkQ) |
+				_TXDMA_VIQ_MAP(viQ) 	| _TXDMA_VOQ_MAP(voQ) |
+				_TXDMA_MGQ_MAP(mgtQ)| _TXDMA_HIQ_MAP(hiQ);
+
+	rtw_write16(Adapter, REG_TRXDMA_CTRL, value16);
+}
+
+static VOID
+_InitNormalChipOneOutEpPriority(
+	IN	PADAPTER Adapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(Adapter);
+
+	u16	value = 0;
+	switch(pHalData->OutEpQueueSel)
+	{
+		case TX_SELE_HQ:
+			value = QUEUE_HIGH;
+			break;
+		case TX_SELE_LQ:
+			value = QUEUE_LOW;
+			break;
+		case TX_SELE_NQ:
+			value = QUEUE_NORMAL;
+			break;
+		default:
+			//RT_ASSERT(FALSE,("Shall not reach here!\n"));
+			break;
+	}
+
+	_InitNormalChipRegPriority(Adapter,
+								value,
+								value,
+								value,
+								value,
+								value,
+								value
+								);
+
+}
+
+static VOID
+_InitNormalChipTwoOutEpPriority(
+	IN	PADAPTER Adapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(Adapter);
+	struct registry_priv *pregistrypriv = &Adapter->registrypriv;
+	u16			beQ,bkQ,viQ,voQ,mgtQ,hiQ;
+
+
+	u16	valueHi = 0;
+	u16	valueLow = 0;
+
+	switch(pHalData->OutEpQueueSel)
+	{
+		case (TX_SELE_HQ | TX_SELE_LQ):
+			valueHi = QUEUE_HIGH;
+			valueLow = QUEUE_LOW;
+			break;
+		case (TX_SELE_NQ | TX_SELE_LQ):
+			valueHi = QUEUE_NORMAL;
+			valueLow = QUEUE_LOW;
+			break;
+		case (TX_SELE_HQ | TX_SELE_NQ):
+			valueHi = QUEUE_HIGH;
+			valueLow = QUEUE_NORMAL;
+			break;
+		default:
+			//RT_ASSERT(FALSE,("Shall not reach here!\n"));
+			break;
+	}
+
+	if(!pregistrypriv->wifi_spec ){
+		beQ		= valueLow;
+		bkQ		= valueLow;
+		viQ		= valueHi;
+		voQ		= valueHi;
+		mgtQ	= valueHi;
+		hiQ		= valueHi;
+	}
+	else{//for WMM ,CONFIG_OUT_EP_WIFI_MODE
+		beQ		= valueLow;
+		bkQ		= valueHi;
+		viQ		= valueHi;
+		voQ		= valueLow;
+		mgtQ	= valueHi;
+		hiQ		= valueHi;
+	}
+
+	_InitNormalChipRegPriority(Adapter,beQ,bkQ,viQ,voQ,mgtQ,hiQ);
+
+}
+
+static VOID
+_InitNormalChipThreeOutEpPriority(
+	IN	PADAPTER padapter
+	)
+{
+	struct registry_priv *pregistrypriv = &padapter->registrypriv;
+	u16			beQ, bkQ, viQ, voQ, mgtQ, hiQ;
+
+	if (!pregistrypriv->wifi_spec){// typical setting
+		beQ		= QUEUE_LOW;
+		bkQ 		= QUEUE_LOW;
+		viQ 		= QUEUE_NORMAL;
+		voQ 		= QUEUE_HIGH;
+		mgtQ 	= QUEUE_HIGH;
+		hiQ 		= QUEUE_HIGH;
+	}
+	else {// for WMM
+		beQ		= QUEUE_LOW;
+		bkQ 		= QUEUE_NORMAL;
+		viQ 		= QUEUE_NORMAL;
+		voQ 		= QUEUE_HIGH;
+		mgtQ 	= QUEUE_HIGH;
+		hiQ 		= QUEUE_HIGH;
+	}
+	_InitNormalChipRegPriority(padapter,beQ,bkQ,viQ,voQ,mgtQ,hiQ);
+}
+
+static VOID
+_InitNormalChipQueuePriority(
+	IN	PADAPTER Adapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(Adapter);
+
+	switch(pHalData->OutEpNumber)
+	{
+		case 1:
+			_InitNormalChipOneOutEpPriority(Adapter);
+			break;
+		case 2:
+			_InitNormalChipTwoOutEpPriority(Adapter);
+			break;
+		case 3:
+			_InitNormalChipThreeOutEpPriority(Adapter);
+			break;
+		default:
+			//RT_ASSERT(FALSE,("Shall not reach here!\n"));
+			break;
+	}
+
+
+}
+
+static void _InitQueuePriority(PADAPTER padapter)
+{
+	_InitNormalChipQueuePriority(padapter);
+}
+
+static void _InitPageBoundary(PADAPTER padapter)
+{
+	// RX Page Boundary
+	u16 rxff_bndy = RX_DMA_BOUNDARY_8703B;
+
+	rtw_write16(padapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
+}
+
+static void _InitTransferPageSize(PADAPTER padapter)
+{
+	// Tx page size is always 128.
+
+	u8 value8;
+	value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
+	rtw_write8(padapter, REG_PBP, value8);
+}
+
+void _InitDriverInfoSize(PADAPTER padapter, u8 drvInfoSize)
+{
+	rtw_write8(padapter, REG_RX_DRVINFO_SZ, drvInfoSize);
+}
+
+void _InitNetworkType(PADAPTER padapter)
+{
+	u32 value32;
+
+	value32 = rtw_read32(padapter, REG_CR);
+
+	// TODO: use the other function to set network type
+//	value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AD_HOC);
+	value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
+
+	rtw_write32(padapter, REG_CR, value32);
+}
+
+void _InitWMACSetting(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	u16 value16;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	pHalData->ReceiveConfig = 0;
+	pHalData->ReceiveConfig |= RCR_APM | RCR_AM | RCR_AB;
+	pHalData->ReceiveConfig |= RCR_CBSSID_DATA | RCR_CBSSID_BCN | RCR_AMF;
+	pHalData->ReceiveConfig |= RCR_HTC_LOC_CTRL;
+	pHalData->ReceiveConfig |= RCR_APP_PHYST_RXFF | RCR_APP_ICV | RCR_APP_MIC;
+#ifdef CONFIG_MAC_LOOPBACK_DRIVER
+	pHalData->ReceiveConfig |= RCR_AAP;
+	pHalData->ReceiveConfig |= RCR_ADD3 | RCR_APWRMGT | RCR_ACRC32 | RCR_ADF;
+#endif
+	rtw_write32(padapter, REG_RCR, pHalData->ReceiveConfig);
+
+	// Accept all multicast address
+	rtw_write32(padapter, REG_MAR, 0xFFFFFFFF);
+	rtw_write32(padapter, REG_MAR + 4, 0xFFFFFFFF);
+
+	// Accept all data frames
+	value16 = 0xFFFF;
+	rtw_write16(padapter, REG_RXFLTMAP2, value16);
+
+	// 2010.09.08 hpfan
+	// Since ADF is removed from RCR, ps-poll will not be indicate to driver,
+	// RxFilterMap should mask ps-poll to gurantee AP mode can rx ps-poll.
+	value16 = 0x400;
+	rtw_write16(padapter, REG_RXFLTMAP1, value16);
+
+	// Accept all management frames
+	value16 = 0xFFFF;
+	rtw_write16(padapter, REG_RXFLTMAP0, value16);
+}
+
+void _InitAdaptiveCtrl(PADAPTER padapter)
+{
+	u16	value16;
+	u32	value32;
+
+	// Response Rate Set
+	value32 = rtw_read32(padapter, REG_RRSR);
+	value32 &= ~RATE_BITMAP_ALL;
+	value32 |= RATE_RRSR_CCK_ONLY_1M;
+	rtw_write32(padapter, REG_RRSR, value32);
+
+	// CF-END Threshold
+	//m_spIoBase->rtw_write8(REG_CFEND_TH, 0x1);
+
+	// SIFS (used in NAV)
+	value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
+	rtw_write16(padapter, REG_SPEC_SIFS, value16);
+
+	// Retry Limit
+	value16 = _LRL(0x30) | _SRL(0x30);
+	rtw_write16(padapter, REG_RL, value16);
+}
+
+void _InitEDCA(PADAPTER padapter)
+{
+	// Set Spec SIFS (used in NAV)
+	rtw_write16(padapter, REG_SPEC_SIFS, 0x100a);
+	rtw_write16(padapter, REG_MAC_SPEC_SIFS, 0x100a);
+
+	// Set SIFS for CCK
+	rtw_write16(padapter, REG_SIFS_CTX, 0x100a);
+
+	// Set SIFS for OFDM
+	rtw_write16(padapter, REG_SIFS_TRX, 0x100a);
+
+	// TXOP
+	rtw_write32(padapter, REG_EDCA_BE_PARAM, 0x005EA42B);
+	rtw_write32(padapter, REG_EDCA_BK_PARAM, 0x0000A44F);
+	rtw_write32(padapter, REG_EDCA_VI_PARAM, 0x005EA324);
+	rtw_write32(padapter, REG_EDCA_VO_PARAM, 0x002FA226);
+}
+
+void _InitRateFallback(PADAPTER padapter)
+{
+	// Set Data Auto Rate Fallback Retry Count register.
+	rtw_write32(padapter, REG_DARFRC, 0x00000000);
+	rtw_write32(padapter, REG_DARFRC+4, 0x10080404);
+	rtw_write32(padapter, REG_RARFRC, 0x04030201);
+	rtw_write32(padapter, REG_RARFRC+4, 0x08070605);
+
+}
+
+void _InitRetryFunction(PADAPTER padapter)
+{
+	u8	value8;
+
+	value8 = rtw_read8(padapter, REG_FWHW_TXQ_CTRL);
+	value8 |= EN_AMPDU_RTY_NEW;
+	rtw_write8(padapter, REG_FWHW_TXQ_CTRL, value8);
+
+	// Set ACK timeout
+	rtw_write8(padapter, REG_ACKTO, 0x40);
+}
+
+static void HalRxAggr8703BSdio(PADAPTER padapter)
+{
+	struct registry_priv *pregistrypriv;
+	u8	valueDMATimeout;
+	u8	valueDMAPageCount;
+
+
+	pregistrypriv = &padapter->registrypriv;
+
+	if (pregistrypriv->wifi_spec)
+	{
+		// 2010.04.27 hpfan
+		// Adjust RxAggrTimeout to close to zero disable RxAggr, suggested by designer
+		// Timeout value is calculated by 34 / (2^n)
+		valueDMATimeout = 0x06;
+		valueDMAPageCount = 0x06;
+	}
+	else
+	{
+		// 20130530, Isaac@SD1 suggest 3 kinds of parameter
+#if 1
+		// TX/RX Balance
+		valueDMATimeout = 0x06;
+		valueDMAPageCount = 0x06;
+#endif
+#if 0
+		// TX/RX Balance, but TCP ack may be late
+		valueDMATimeout = 0x16;
+		valueDMAPageCount = 0x06;
+#endif
+#if 0
+		// RX Best
+		valueDMATimeout = 0x16;
+		valueDMAPageCount = 0x08;
+#endif
+	}
+
+#ifdef CONFIG_DONT_CARE_TP
+	valueDMATimeout = 0x0f;
+	valueDMAPageCount = 0x04;  //RxAggUpthreshold = [4]*1K bytes+1.5k.  since RxAggUpthreshold+SzAmsdu(3839)<MaxRxBuffSize(8k), MaxvalueDMAPageCount=4.
+#endif
+	rtw_write8(padapter, REG_RXDMA_AGG_PG_TH+1, valueDMATimeout);
+	rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, valueDMAPageCount);
+}
+
+void sdio_AggSettingRxUpdate(PADAPTER padapter)
+{
+	HAL_DATA_TYPE *pHalData;
+	u8 valueDMA;
+	u8 valueRxAggCtrl = 0;
+	u8 aggBurstNum = 3;  //0:1, 1:2, 2:3, 3:4
+	u8 aggBurstSize = 0;  //0:1K, 1:512Byte, 2:256Byte...
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	valueDMA = rtw_read8(padapter, REG_TRXDMA_CTRL);
+	valueDMA |= RXDMA_AGG_EN;
+	rtw_write8(padapter, REG_TRXDMA_CTRL, valueDMA);
+
+	valueRxAggCtrl |= RXDMA_AGG_MODE_EN;
+	valueRxAggCtrl |= ((aggBurstNum<<2) & 0x0C);
+	valueRxAggCtrl |= ((aggBurstSize<<4) & 0x30);  
+	rtw_write8(padapter, REG_RXDMA_MODE_CTRL_8703B, valueRxAggCtrl);//RxAggLowThresh = 4*1K
+}
+
+void _initSdioAggregationSetting(PADAPTER padapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+	// Tx aggregation setting
+//	sdio_AggSettingTxUpdate(padapter);
+
+	// Rx aggregation setting
+	HalRxAggr8703BSdio(padapter);
+
+	sdio_AggSettingRxUpdate(padapter);
+}
+
+static void _RXAggrSwitch(PADAPTER padapter, u8 enable)
+{
+	PHAL_DATA_TYPE pHalData;
+	u8 valueDMA;
+	u8 valueRxAggCtrl;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	valueDMA = rtw_read8(padapter, REG_TRXDMA_CTRL);
+	valueRxAggCtrl = rtw_read8(padapter, REG_RXDMA_MODE_CTRL_8703B);
+
+	if (_TRUE == enable)
+	{
+		valueDMA |= RXDMA_AGG_EN;
+		valueRxAggCtrl |= RXDMA_AGG_MODE_EN;
+	}
+	else
+	{
+		valueDMA &= ~RXDMA_AGG_EN;
+		valueRxAggCtrl &= ~RXDMA_AGG_MODE_EN;
+	}
+
+	rtw_write8(padapter, REG_TRXDMA_CTRL, valueDMA);
+	rtw_write8(padapter, REG_RXDMA_MODE_CTRL_8703B, valueRxAggCtrl);
+}
+
+void _InitOperationMode(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	struct mlme_ext_priv *pmlmeext;
+	u8				regBwOpMode = 0;
+	u32				regRATR = 0, regRRSR = 0;
+	u8				MinSpaceCfg = 0;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	pmlmeext = &padapter->mlmeextpriv;
+
+	//1 This part need to modified according to the rate set we filtered!!
+	//
+	// Set RRSR, RATR, and REG_BWOPMODE registers
+	//
+	switch(pmlmeext->cur_wireless_mode)
+	{
+		case WIRELESS_MODE_B:
+			regBwOpMode = BW_OPMODE_20MHZ;
+			regRATR = RATE_ALL_CCK;
+			regRRSR = RATE_ALL_CCK;
+			break;
+		case WIRELESS_MODE_A:
+//			RT_ASSERT(FALSE,("Error wireless a mode\n"));
+#if 0
+			regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
+			regRATR = RATE_ALL_OFDM_AG;
+			regRRSR = RATE_ALL_OFDM_AG;
+#endif
+			break;
+		case WIRELESS_MODE_G:
+			regBwOpMode = BW_OPMODE_20MHZ;
+			regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+			regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+			break;
+		case WIRELESS_MODE_AUTO:
+#if 0
+			if (padapter->bInHctTest)
+			{
+				regBwOpMode = BW_OPMODE_20MHZ;
+				regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+				regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+			}
+			else
+#endif
+			{
+				regBwOpMode = BW_OPMODE_20MHZ;
+				regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+				regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+			}
+			break;
+		case WIRELESS_MODE_N_24G:
+			// It support CCK rate by default.
+			// CCK rate will be filtered out only when associated AP does not support it.
+			regBwOpMode = BW_OPMODE_20MHZ;
+			regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+			regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+			break;
+		case WIRELESS_MODE_N_5G:
+//			RT_ASSERT(FALSE,("Error wireless mode"));
+#if 0
+			regBwOpMode = BW_OPMODE_5G;
+			regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+			regRRSR = RATE_ALL_OFDM_AG;
+#endif
+			break;
+
+		default: //for MacOSX compiler warning.
+			break;
+	}
+
+	rtw_write8(padapter, REG_BWOPMODE, regBwOpMode);
+
+}
+
+void _InitInterrupt(PADAPTER padapter)
+{
+	// HISR - turn all off
+	rtw_write32(padapter, REG_HISR, 0);
+
+	// HIMR - turn all off
+	rtw_write32(padapter, REG_HIMR, 0);
+
+	//
+	// Initialize and enable SDIO Host Interrupt.
+	//
+	InitInterrupt8703BSdio(padapter);
+
+	//
+	// Initialize system Host Interrupt.
+	//
+	InitSysInterrupt8703BSdio(padapter);
+}
+
+void _InitRDGSetting(PADAPTER padapter)
+{
+	rtw_write8(padapter, REG_RD_CTRL, 0xFF);
+	rtw_write16(padapter, REG_RD_NAV_NXT, 0x200);
+	rtw_write8(padapter, REG_RD_RESP_PKT_TH, 0x05);
+}
+
+static void _InitRFType(PADAPTER padapter)
+{
+	struct registry_priv *pregpriv = &padapter->registrypriv;
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+#if	DISABLE_BB_RF
+	pHalData->rf_chip	= RF_PSEUDO_11N;
+	return;
+#endif
+	pHalData->rf_chip	= RF_6052;
+
+	MSG_8192C("Set RF Chip ID to RF_6052 and RF type to %d.\n", pHalData->rf_type);
+}
+
+// Set CCK and OFDM Block "ON"
+static void _BBTurnOnBlock(PADAPTER padapter)
+{
+#if (DISABLE_BB_RF)
+	return;
+#endif
+
+	PHY_SetBBReg(padapter, rFPGA0_RFMOD, bCCKEn, 0x1);
+	PHY_SetBBReg(padapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
+}
+
+static void _RfPowerSave(PADAPTER padapter)
+{
+//YJ,TODO
+}
+
+static void _InitAntenna_Selection(PADAPTER padapter)
+{
+	rtw_write8(padapter, REG_LEDCFG2, 0x82);
+}
+
+static void _InitPABias(PADAPTER padapter)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(padapter);
+	u8			pa_setting;
+
+	//FIXED PA current issue
+	//efuse_one_byte_read(padapter, 0x1FA, &pa_setting);
+	pa_setting = EFUSE_Read1Byte(padapter, 0x1FA);
+
+	//RT_TRACE(COMP_INIT, DBG_LOUD, ("_InitPABias 0x1FA 0x%x \n",pa_setting));
+
+	if(!(pa_setting & BIT0))
+	{
+		PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x0F406);
+		PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x4F406);
+		PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x8F406);
+		PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0xCF406);
+		//RT_TRACE(COMP_INIT, DBG_LOUD, ("PA BIAS path A\n"));
+	}
+
+	if(!(pa_setting & BIT4))
+	{
+		pa_setting = rtw_read8(padapter, 0x16);
+		pa_setting &= 0x0F;
+		rtw_write8(padapter, 0x16, pa_setting | 0x80);
+		rtw_write8(padapter, 0x16, pa_setting | 0x90);
+	}
+}
+
+VOID _InitBBRegBackup_8703BS(PADAPTER	Adapter)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+
+	/* For Channel 1~11 (Default Value)*/
+	pHalData->RegForRecover[0].offset = rCCK0_TxFilter2;
+	pHalData->RegForRecover[0].value = PHY_QueryBBReg(Adapter, pHalData->RegForRecover[0].offset, bMaskDWord);
+
+	pHalData->RegForRecover[1].offset = rCCK0_DebugPort;
+	pHalData->RegForRecover[1].value = PHY_QueryBBReg(Adapter, pHalData->RegForRecover[1].offset, bMaskDWord);
+
+	/* For 20 MHz	(Default Value)*/
+	pHalData->RegForRecover[2].offset = rBBrx_DFIR;
+	pHalData->RegForRecover[2].value = PHY_QueryBBReg(Adapter, pHalData->RegForRecover[2].offset, bMaskDWord);
+
+	pHalData->RegForRecover[3].offset = rOFDM0_XATxAFE;
+	pHalData->RegForRecover[3].value = PHY_QueryBBReg(Adapter, pHalData->RegForRecover[3].offset, bMaskDWord);
+
+	pHalData->RegForRecover[4].offset = 0x1E;
+	pHalData->RegForRecover[4].value = PHY_QueryRFReg(Adapter, ODM_RF_PATH_A, pHalData->RegForRecover[4].offset, bRFRegOffsetMask);
+}
+
+//
+// 2010/08/09 MH Add for power down check.
+//
+static BOOLEAN HalDetectPwrDownMode(PADAPTER Adapter)
+{
+	u8 tmpvalue;
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(Adapter);
+
+
+	EFUSE_ShadowRead(Adapter, 1, EEPROM_FEATURE_OPTION_8703B, (u32 *)&tmpvalue);
+
+	// 2010/08/25 MH INF priority > PDN Efuse value.
+	if(tmpvalue & BIT4 && pwrctrlpriv->reg_pdnmode)
+	{
+		pHalData->pwrdown = _TRUE;
+	}
+	else
+	{
+		pHalData->pwrdown = _FALSE;
+	}
+
+	DBG_8192C("HalDetectPwrDownMode(): PDN=%d\n", pHalData->pwrdown);
+
+	return pHalData->pwrdown;
+}	// HalDetectPwrDownMode
+
+static u32 rtl8703bs_hal_init(PADAPTER padapter)
+{
+	s32 ret;
+	PHAL_DATA_TYPE pHalData;
+	struct pwrctrl_priv *pwrctrlpriv;
+	struct registry_priv *pregistrypriv;
+	struct sreset_priv *psrtpriv;
+	struct dvobj_priv *psdpriv = padapter->dvobj;
+	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+	rt_rf_power_state eRfPowerStateToSet;
+	u32 NavUpper = WiFiNavUpperUs;
+	u8 u1bTmp;
+	u16 value16;
+	u8 typeid;
+	u32 u4Tmp;
+
+	pHalData = GET_HAL_DATA(padapter);
+	psrtpriv = &pHalData->srestpriv;
+	pwrctrlpriv = adapter_to_pwrctl(padapter);
+	pregistrypriv = &padapter->registrypriv;
+
+#ifdef CONFIG_SWLPS_IN_IPS
+	if (adapter_to_pwrctl(padapter)->bips_processing == _TRUE)
+	{
+		u8 val8, bMacPwrCtrlOn = _TRUE;
+
+		DBG_871X("%s: run LPS flow in IPS\n", __FUNCTION__);
+
+		//ser rpwm
+		val8 = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1);
+		val8 &= 0x80;
+		val8 += 0x80;	
+		val8 |= BIT(6);		
+		rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8);
+		
+		adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
+		
+		rtw_mdelay_os(5); //wait set rpwm already
+		
+		ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8703B_leave_swlps_flow);
+		if (ret == _FALSE) {
+			DBG_8192C("%s: run LPS flow in IPS fail!\n", __FUNCTION__);
+			return _FAIL;
+		}
+
+		rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+
+		pHalData->LastHMEBoxNum = 0;
+
+#ifdef CONFIG_BT_COEXIST
+		rtw_btcoex_HAL_Initialize(padapter, _FALSE);
+#else
+		rtw_btcoex_HAL_Initialize(padapter, _TRUE);
+#endif // CONFIG_BT_COEXIST
+
+		return _SUCCESS;
+	}
+#elif defined(CONFIG_FWLPS_IN_IPS)
+	if (adapter_to_pwrctl(padapter)->bips_processing == _TRUE && psrtpriv->silent_reset_inprogress == _FALSE
+		&& adapter_to_pwrctl(padapter)->pre_ips_type == 0)
+	{
+		u32 start_time;
+		u8 cpwm_orig, cpwm_now;
+		u8 val8, bMacPwrCtrlOn = _TRUE;
+
+		DBG_871X("%s: Leaving IPS in FWLPS state\n", __FUNCTION__);
+
+		//for polling cpwm
+		cpwm_orig = 0;
+		rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
+
+		//ser rpwm
+		val8 = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1);
+		val8 &= 0x80;
+		val8 += 0x80;	
+		val8 |= BIT(6);		
+		rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8);
+		DBG_871X("%s: write rpwm=%02x\n", __FUNCTION__, val8);
+		adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
+
+		//do polling cpwm
+		start_time = rtw_get_current_time();		
+		do {
+
+			rtw_mdelay_os(1);
+			
+			rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
+			if ((cpwm_orig ^ cpwm_now) & 0x80)
+			{		
+#ifdef DBG_CHECK_FW_PS_STATE				
+				DBG_871X("%s: polling cpwm ok when leaving IPS in FWLPS state, cpwm_orig=%02x, cpwm_now=%02x, 0x100=0x%x \n"
+				, __FUNCTION__, cpwm_orig, cpwm_now, rtw_read8(padapter, REG_CR));
+#endif //DBG_CHECK_FW_PS_STATE
+				break;
+			}
+
+			if (rtw_get_passing_time_ms(start_time) > 100)
+			{
+				DBG_871X("%s: polling cpwm timeout when leaving IPS in FWLPS state\n", __FUNCTION__);
+				break;
+			}			
+		} while (1);
+
+		rtl8703b_set_FwPwrModeInIPS_cmd(padapter, 0);
+
+		rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);		
+
+#ifdef CONFIG_BT_COEXIST
+		rtw_btcoex_HAL_Initialize(padapter, _FALSE);
+#else
+		rtw_btcoex_HAL_Initialize(padapter, _TRUE);
+#endif // CONFIG_BT_COEXIST
+
+#ifdef DBG_CHECK_FW_PS_STATE
+		if(rtw_fw_ps_state(padapter) == _FAIL)
+		{
+			DBG_871X("after hal init, fw ps state in 32k\n");
+			pdbgpriv->dbg_ips_drvopen_fail_cnt++;
+		}
+#endif //DBG_CHECK_FW_PS_STATE
+		return _SUCCESS;
+	}	
+#endif //CONFIG_SWLPS_IN_IPS
+
+	// Disable Interrupt first.
+//	rtw_hal_disable_interrupt(padapter);
+
+	if(rtw_read8(padapter, REG_MCUFWDL) == 0xc6) {
+		DBG_871X("FW exist before power on!!\n");
+	} else {
+		DBG_871X("FW does not exist before power on!!\n");
+	}
+
+	if(rtw_fw_ps_state(padapter) == _FAIL)
+	{
+		DBG_871X("check fw_ps_state fail before PowerOn!\n");
+		pdbgpriv->dbg_ips_drvopen_fail_cnt++;
+	}
+	
+	ret = rtw_hal_power_on(padapter);
+	if (_FAIL == ret) {
+		RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("Failed to init Power On!\n"));
+		return _FAIL;
+	}
+	DBG_871X("Power on ok!\n");
+	
+	if(rtw_fw_ps_state(padapter) == _FAIL)
+	{
+		DBG_871X("check fw_ps_state fail after PowerOn!\n");
+		pdbgpriv->dbg_ips_drvopen_fail_cnt++;
+	}	
+	
+
+	rtw_write8(padapter, REG_EARLY_MODE_CONTROL, 0);
+
+	if (padapter->registrypriv.mp_mode == 0) {
+		ret = rtl8703b_FirmwareDownload(padapter, _FALSE);
+		if (ret != _SUCCESS) {
+			RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("%s: Download Firmware failed!!\n", __FUNCTION__));
+			padapter->bFWReady = _FALSE;
+			pHalData->fw_ractrl = _FALSE;
+			return ret;
+		} else {
+			RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("rtl8703bs_hal_init(): Download Firmware Success!!\n"));
+			padapter->bFWReady = _TRUE;
+			pHalData->fw_ractrl = _TRUE;
+		}
+	}
+
+//	SIC_Init(padapter);
+
+	if (pwrctrlpriv->reg_rfoff == _TRUE) {
+		pwrctrlpriv->rf_pwrstate = rf_off;
+	}
+
+	// 2010/08/09 MH We need to check if we need to turnon or off RF after detecting
+	// HW GPIO pin. Before PHY_RFConfig8192C.
+	HalDetectPwrDownMode(padapter);
+
+	// Set RF type for BB/RF configuration
+	_InitRFType(padapter);
+
+	// Save target channel
+	// <Roger_Notes> Current Channel will be updated again later.
+	pHalData->CurrentChannel = 6;
+
+#if (HAL_MAC_ENABLE == 1)
+	ret = PHY_MACConfig8703B(padapter);
+	if(ret != _SUCCESS){
+		RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure MAC!!\n"));
+		return ret;
+	}
+#endif
+	//
+	//d. Initialize BB related configurations.
+	//
+#if (HAL_BB_ENABLE == 1)
+	ret = PHY_BBConfig8703B(padapter);
+	if(ret != _SUCCESS){
+		RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure BB!!\n"));
+		return ret;
+	}
+
+#endif
+
+	// If RF is on, we need to init RF. Otherwise, skip the procedure.
+	// We need to follow SU method to change the RF cfg.txt. Default disable RF TX/RX mode.
+	//if(pHalData->eRFPowerState == eRfOn)
+	{
+#if (HAL_RF_ENABLE == 1)
+		ret = PHY_RFConfig8703B(padapter);
+		if(ret != _SUCCESS){
+			RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure RF!!\n"));
+			return ret;
+		}
+#endif
+	}
+
+	_InitBBRegBackup_8703BS(padapter);
+
+	_InitMacAPLLSetting_8703B(padapter);
+
+	//
+	// Joseph Note: Keep RfRegChnlVal for later use.
+	//
+	pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(padapter, (RF_PATH)0, RF_CHNLBW, bRFRegOffsetMask);
+	pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(padapter, (RF_PATH)1, RF_CHNLBW, bRFRegOffsetMask);
+
+#if 0
+	/* Specially add for FWDL by Tx pkt write. Reset Tx/Rx DMA since the Tx boundary setting
+		is changed during FW download */
+	rtw_write8(padapter, REG_CR, 0x00);
+	rtw_write8(padapter, REG_CR, 0xFF);
+#endif
+	
+	//if (!pHalData->bMACFuncEnable) {
+		_InitQueueReservedPage(padapter);
+		_InitTxBufferBoundary(padapter);
+
+		// init LLT after tx buffer boundary is defined
+		ret = rtl8703b_InitLLTTable(padapter);
+		if (_SUCCESS != ret)
+		{
+			DBG_8192C("%s: Failed to init LLT Table!\n", __FUNCTION__);
+			return _FAIL;
+		}
+	//}
+	_InitQueuePriority(padapter);
+	_InitPageBoundary(padapter);
+	_InitTransferPageSize(padapter);
+
+	// Get Rx PHY status in order to report RSSI and others.
+	_InitDriverInfoSize(padapter, DRVINFO_SZ);
+	hal_init_macaddr(padapter);
+	_InitNetworkType(padapter);
+	_InitWMACSetting(padapter);
+	_InitAdaptiveCtrl(padapter);
+	_InitEDCA(padapter);
+	//_InitRateFallback(padapter);
+	_InitRetryFunction(padapter);
+	_initSdioAggregationSetting(padapter);
+	_InitOperationMode(padapter);
+	rtl8703b_InitBeaconParameters(padapter);
+	rtl8703b_InitBeaconMaxError(padapter, _TRUE);
+	_InitInterrupt(padapter);
+	_InitBurstPktLen_8703BS(padapter);
+
+#if 0
+	// 8703B new ADD
+	_InitLTECoex_8703BS(padapter);
+#endif
+
+	//YJ,TODO
+	rtw_write8(padapter, REG_SECONDARY_CCA_CTRL_8703B, 0x3);	// CCA 
+	rtw_write8(padapter, 0x976, 0);	// hpfan_todo: 2nd CCA related
+
+#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_TX_MCAST2UNI)
+
+#ifdef CONFIG_CHECK_AC_LIFETIME
+	// Enable lifetime check for the four ACs
+	rtw_write8(padapter, REG_LIFETIME_EN, 0x0F);
+#endif	// CONFIG_CHECK_AC_LIFETIME
+
+#ifdef CONFIG_TX_MCAST2UNI
+	rtw_write16(padapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400);	// unit: 256us. 256ms
+	rtw_write16(padapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400);	// unit: 256us. 256ms
+#else	// CONFIG_TX_MCAST2UNI
+	rtw_write16(padapter, REG_PKT_VO_VI_LIFE_TIME, 0x3000);	// unit: 256us. 3s
+	rtw_write16(padapter, REG_PKT_BE_BK_LIFE_TIME, 0x3000);	// unit: 256us. 3s
+#endif	// CONFIG_TX_MCAST2UNI
+#endif	// CONFIG_CONCURRENT_MODE || CONFIG_TX_MCAST2UNI
+
+
+	invalidate_cam_all(padapter);
+
+	rtw_hal_set_chnl_bw(padapter, padapter->registrypriv.channel,
+		CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
+
+	// Record original value for template. This is arough data, we can only use the data
+	// for power adjust. The value can not be adjustde according to different power!!!
+//	pHalData->OriginalCckTxPwrIdx = pHalData->CurrentCckTxPwrIdx;
+//	pHalData->OriginalOfdm24GTxPwrIdx = pHalData->CurrentOfdm24GTxPwrIdx;
+
+	rtl8703b_InitAntenna_Selection(padapter);
+
+	//
+	// Disable BAR, suggested by Scott
+	// 2010.04.09 add by hpfan
+	//
+	rtw_write32(padapter, REG_BAR_MODE_CTRL, 0x0201ffff);
+
+	// HW SEQ CTRL
+	// set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM.
+	rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF);
+
+
+#ifdef CONFIG_MAC_LOOPBACK_DRIVER
+	u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN);
+	u1bTmp &= ~(FEN_BBRSTB|FEN_BB_GLB_RSTn);
+	rtw_write8(padapter, REG_SYS_FUNC_EN,u1bTmp);
+
+	rtw_write8(padapter, REG_RD_CTRL, 0x0F);
+	rtw_write8(padapter, REG_RD_CTRL+1, 0xCF);
+	rtw_write8(padapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, 0x80);
+	rtw_write32(padapter, REG_CR, 0x0b0202ff);
+#endif
+
+	//
+	// Configure SDIO TxRx Control to enable Rx DMA timer masking.
+	// 2010.02.24.
+	//
+	rtw_write32(padapter, SDIO_LOCAL_BASE|SDIO_REG_TX_CTRL, 0);
+
+	_RfPowerSave(padapter);
+	
+
+	rtl8703b_InitHalDm(padapter);
+
+	//DbgPrint("pHalData->DefaultTxPwrDbm = %d\n", pHalData->DefaultTxPwrDbm);
+
+//	if(pHalData->SwBeaconType < HAL92CSDIO_DEFAULT_BEACON_TYPE) // The lowest Beacon Type that HW can support
+//		pHalData->SwBeaconType = HAL92CSDIO_DEFAULT_BEACON_TYPE;
+
+	//
+	// Update current Tx FIFO page status.
+	//
+	HalQueryTxBufferStatus8703BSdio(padapter);
+	HalQueryTxOQTBufferStatus8703BSdio(padapter);
+	pHalData->SdioTxOQTMaxFreeSpace = pHalData->SdioTxOQTFreeSpace;
+
+	// Enable MACTXEN/MACRXEN block
+	u1bTmp = rtw_read8(padapter, REG_CR);
+	u1bTmp |= (MACTXEN | MACRXEN);
+	rtw_write8(padapter, REG_CR, u1bTmp);
+
+	rtw_hal_set_hwreg(padapter, HW_VAR_NAV_UPPER, (u8*)&NavUpper);
+
+#ifdef CONFIG_XMIT_ACK
+	//ack for xmit mgmt frames.
+	rtw_write32(padapter, REG_FWHW_TXQ_CTRL, rtw_read32(padapter, REG_FWHW_TXQ_CTRL)|BIT(12));
+#endif //CONFIG_XMIT_ACK	
+
+//	pHalData->PreRpwmVal = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HRPWM1) & 0x80;
+
+#if (MP_DRIVER == 1)
+	if (padapter->registrypriv.mp_mode == 1)
+	{
+		padapter->mppriv.channel = pHalData->CurrentChannel;
+		MPT_InitializeAdapter(padapter, padapter->mppriv.channel);
+	}
+	else
+#endif //#if (MP_DRIVER == 1)
+	{
+		pwrctrlpriv->rf_pwrstate = rf_on;
+
+		if(pwrctrlpriv->rf_pwrstate == rf_on)
+		{
+			struct pwrctrl_priv *pwrpriv;
+			u32 start_time;
+			u8 h2cCmdBuf;
+
+			pwrpriv = adapter_to_pwrctl(padapter);
+
+			PHY_LCCalibrate_8703B(&pHalData->odmpriv);
+
+			/* Inform WiFi FW that it is the beginning of IQK */
+			h2cCmdBuf = 1;
+			FillH2CCmd8703B(padapter, H2C_8703B_BT_WLAN_CALIBRATION, 1, &h2cCmdBuf);
+
+			start_time = rtw_get_current_time();
+			do {
+				if (rtw_read8(padapter, 0x1e7) & 0x01)
+					break;
+
+				rtw_msleep_os(50);
+			} while (rtw_get_passing_time_ms(start_time) <= 400);
+
+#ifdef CONFIG_BT_COEXIST
+			rtw_btcoex_IQKNotify(padapter, _TRUE);
+#endif
+			PHY_IQCalibrate_8703B(padapter, _FALSE);
+			pHalData->bIQKInitialized = _TRUE;
+#ifdef CONFIG_BT_COEXIST
+			rtw_btcoex_IQKNotify(padapter, _FALSE);
+#endif
+
+			/* Inform WiFi FW that it is the finish of IQK */
+			h2cCmdBuf = 0;
+			FillH2CCmd8703B(padapter, H2C_8703B_BT_WLAN_CALIBRATION, 1, &h2cCmdBuf);
+
+			ODM_TXPowerTrackingCheck(&pHalData->odmpriv);
+		}
+	}
+
+#ifdef CONFIG_BT_COEXIST
+	/* Init BT hw config.*/
+	if (padapter->registrypriv.mp_mode == 1)
+		rtw_btcoex_HAL_Initialize(padapter, _TRUE);
+	else
+		rtw_btcoex_HAL_Initialize(padapter, _FALSE);
+#endif
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("-%s\n", __FUNCTION__));
+
+	return _SUCCESS;
+}
+
+static void CardDisableRTL8703BSdio(PADAPTER padapter)
+{
+	u8		u1bTmp;
+	u16		u2bTmp;
+	u32		u4bTmp;
+	u8		bMacPwrCtrlOn;
+	u8		ret = _FAIL;
+
+	// Run LPS WL RFOFF flow
+	ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8703B_enter_lps_flow);
+	if (ret == _FAIL) {
+		DBG_8192C(KERN_ERR "%s: run RF OFF flow fail!\n", __func__);
+	}
+
+	//	==== Reset digital sequence   ======
+
+	u1bTmp = rtw_read8(padapter, REG_MCUFWDL);
+	if ((u1bTmp & RAM_DL_SEL) && padapter->bFWReady) //8051 RAM code
+		rtl8703b_FirmwareSelfReset(padapter);
+
+	// Reset MCU 0x2[10]=0. Suggested by Filen. 2011.01.26. by tynli.
+	u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
+	u1bTmp &= ~BIT(2);	// 0x2[10], FEN_CPUEN
+	rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp);
+
+	// MCUFWDL 0x80[1:0]=0
+	// reset MCU ready status
+	rtw_write8(padapter, REG_MCUFWDL, 0);
+
+	// Reset MCU IO Wrapper, added by Roger, 2011.08.30
+	u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1);
+	u1bTmp &= ~BIT(0);
+	rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp);
+	u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1);
+	u1bTmp |= BIT(0);
+	rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp);
+
+	//	==== Reset digital sequence end ======
+	
+	bMacPwrCtrlOn = _FALSE;	// Disable CMD53 R/W
+	ret = _FALSE;
+	rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8703B_card_disable_flow);
+	if (ret == _FALSE) {
+		DBG_8192C(KERN_ERR "%s: run CARD DISABLE flow fail!\n", __func__);
+	}
+
+	padapter->bFWReady = _FALSE;
+}
+
+static u32 rtl8703bs_hal_deinit(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+        struct dvobj_priv *psdpriv = padapter->dvobj;
+	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+
+#ifdef CONFIG_MP_INCLUDED
+	if (padapter->registrypriv.mp_mode == 1)
+		MPT_DeInitAdapter(padapter);
+#endif
+
+	if (rtw_is_hw_init_completed(padapter)) {
+#ifdef CONFIG_SWLPS_IN_IPS				
+		if (adapter_to_pwrctl(padapter)->bips_processing == _TRUE)
+		{
+			u8	bMacPwrCtrlOn;
+			u8 ret =  _TRUE;
+
+			DBG_871X("%s: run LPS flow in IPS\n", __FUNCTION__);
+
+			rtw_write32(padapter, 0x130, 0x0);
+			rtw_write32(padapter, 0x138, 0x100);
+			rtw_write8(padapter, 0x13d, 0x1);
+
+
+			bMacPwrCtrlOn = _FALSE;	// Disable CMD53 R/W	
+			rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+			
+			ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8703B_enter_swlps_flow);
+			if (ret == _FALSE) {
+				DBG_8192C("%s: run LPS flow in IPS fail!\n", __FUNCTION__);
+				return _FAIL;
+			}
+		}
+		else
+#elif defined(CONFIG_FWLPS_IN_IPS)
+		if (adapter_to_pwrctl(padapter)->bips_processing == _TRUE && psrtpriv->silent_reset_inprogress == _FALSE)
+		{
+			if(padapter->netif_up == _TRUE)
+			{
+				int cnt=0;
+				u8 val8 = 0;
+			
+				DBG_871X("%s: issue H2C to FW when entering IPS\n", __FUNCTION__);
+			
+				rtl8703b_set_FwPwrModeInIPS_cmd(padapter, 0x3);
+				//poll 0x1cc to make sure H2C command already finished by FW; MAC_0x1cc=0 means H2C done by FW.
+				do{
+					val8 = rtw_read8(padapter, REG_HMETFR);
+					cnt++;
+					DBG_871X("%s  polling REG_HMETFR=0x%x, cnt=%d \n", __FUNCTION__, val8, cnt);
+					rtw_mdelay_os(10);
+				}while(cnt<100 && (val8!=0));
+				//H2C done, enter 32k
+				if(val8 == 0)
+				{
+					//ser rpwm to enter 32k
+					val8 = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1);
+					val8 += 0x80;
+					val8 |= BIT(0);
+					rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8);
+					DBG_871X("%s: write rpwm=%02x\n", __FUNCTION__, val8);
+					adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
+					cnt = val8 = 0;
+					do{
+						val8 = rtw_read8(padapter, REG_CR);
+						cnt++;
+						DBG_871X("%s  polling 0x100=0x%x, cnt=%d \n", __FUNCTION__, val8, cnt);			
+						rtw_mdelay_os(10);
+					}while(cnt<100 && (val8!=0xEA));
+#ifdef DBG_CHECK_FW_PS_STATE
+				if(val8 != 0xEA)
+					DBG_871X("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n", rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
+					, rtw_read32(padapter, 0x1c8), rtw_read32(padapter, 0x1cc));
+#endif //DBG_CHECK_FW_PS_STATE
+				}
+				else
+				{
+					DBG_871X("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n", rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
+					, rtw_read32(padapter, 0x1c8), rtw_read32(padapter, 0x1cc));
+				}
+			
+				DBG_871X("polling done when entering IPS, check result : 0x100=0x%x, cnt=%d, MAC_1cc=0x%02x\n"
+				, rtw_read8(padapter, REG_CR), cnt, rtw_read8(padapter, REG_HMETFR));
+
+				adapter_to_pwrctl(padapter)->pre_ips_type = 0;
+				
+			}
+			else
+			{
+				pdbgpriv->dbg_carddisable_cnt++;
+#ifdef DBG_CHECK_FW_PS_STATE
+				if(rtw_fw_ps_state(padapter) == _FAIL)
+				{
+					DBG_871X("card disable should leave 32k\n");
+					pdbgpriv->dbg_carddisable_error_cnt++;
+				}
+#endif //DBG_CHECK_FW_PS_STATE
+				rtw_hal_power_off(padapter);
+
+				adapter_to_pwrctl(padapter)->pre_ips_type = 1;
+			}
+			
+		}
+		else
+#endif //CONFIG_SWLPS_IN_IPS
+		{
+			pdbgpriv->dbg_carddisable_cnt++;
+#ifdef DBG_CHECK_FW_PS_STATE
+			if(rtw_fw_ps_state(padapter) == _FAIL)
+			{
+				DBG_871X("card disable should leave 32k\n");
+				pdbgpriv->dbg_carddisable_error_cnt++;
+			}
+#endif //DBG_CHECK_FW_PS_STATE
+			rtw_hal_power_off(padapter);
+		}
+	}
+	else
+	{
+		pdbgpriv->dbg_deinit_fail_cnt++;
+	}
+
+	return _SUCCESS;
+}
+static void rtl8703bs_init_default_value(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	rtl8703b_init_default_value(padapter);
+
+	// interface related variable
+	pHalData->SdioRxFIFOCnt = 0;
+}
+
+static void rtl8703bs_interface_configure(PADAPTER padapter)
+{
+	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(padapter);
+	struct dvobj_priv		*pdvobjpriv = adapter_to_dvobj(padapter);
+	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
+	BOOLEAN		bWiFiConfig	= pregistrypriv->wifi_spec;
+
+
+	pdvobjpriv->RtOutPipe[0] = WLAN_TX_HIQ_DEVICE_ID;
+	pdvobjpriv->RtOutPipe[1] = WLAN_TX_MIQ_DEVICE_ID;
+	pdvobjpriv->RtOutPipe[2] = WLAN_TX_LOQ_DEVICE_ID;
+
+	if (bWiFiConfig)
+		pHalData->OutEpNumber = 2;
+	else
+		pHalData->OutEpNumber = SDIO_MAX_TX_QUEUE;
+
+	switch(pHalData->OutEpNumber){
+		case 3:
+			pHalData->OutEpQueueSel=TX_SELE_HQ| TX_SELE_LQ|TX_SELE_NQ;
+			break;
+		case 2:
+			pHalData->OutEpQueueSel=TX_SELE_HQ| TX_SELE_NQ;
+			break;
+		case 1:
+			pHalData->OutEpQueueSel=TX_SELE_HQ;
+			break;
+		default:
+			break;
+	}
+
+	Hal_MappingOutPipe(padapter, pHalData->OutEpNumber);
+}
+
+//
+//	Description:
+//		We should set Efuse cell selection to WiFi cell in default.
+//
+//	Assumption:
+//		PASSIVE_LEVEL
+//
+//	Added by Roger, 2010.11.23.
+//
+static void
+_EfuseCellSel(
+	IN	PADAPTER	padapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
+
+	u32			value32;
+
+	//if(INCLUDE_MULTI_FUNC_BT(padapter))
+	{
+		value32 = rtw_read32(padapter, EFUSE_TEST);
+		value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
+		rtw_write32(padapter, EFUSE_TEST, value32);
+	}
+}
+
+static VOID
+_ReadRFType(
+	IN	PADAPTER	Adapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+
+#if DISABLE_BB_RF
+	pHalData->rf_chip = RF_PSEUDO_11N;
+#else
+	pHalData->rf_chip = RF_6052;
+#endif
+}
+
+static VOID
+_ReadEfuseInfo8703BS(
+	IN PADAPTER			padapter
+	)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	u8*			hwinfo = NULL;
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("====>_ReadEfuseInfo8703BS()\n"));
+
+	//
+	// This part read and parse the eeprom/efuse content
+	//
+
+	if (sizeof(pHalData->efuse_eeprom_data) < HWSET_MAX_SIZE_8703B)
+		DBG_871X("[WARNING] size of efuse_eeprom_data is less than HWSET_MAX_SIZE_8703B!\n");
+
+	hwinfo = pHalData->efuse_eeprom_data;
+
+	Hal_InitPGData(padapter, hwinfo);
+
+	Hal_EfuseParseIDCode(padapter, hwinfo);
+	Hal_EfuseParseEEPROMVer_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	hal_config_macaddr(padapter, pHalData->bautoload_fail_flag);
+	Hal_EfuseParseTxPowerInfo_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	Hal_EfuseParseBoardType_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+
+	//
+	// Read Bluetooth co-exist and initialize
+	//
+	Hal_EfuseParseBTCoexistInfo_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	Hal_EfuseParseChnlPlan_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	Hal_EfuseParseXtal_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	Hal_EfuseParseThermalMeter_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	Hal_EfuseParseAntennaDiversity_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	Hal_EfuseParseCustomerID_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	
+	Hal_EfuseParseVoltage_8703B(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	
+#ifdef CONFIG_WOWLAN
+	Hal_DetectWoWMode(padapter);
+#endif
+
+	Hal_ReadRFGainOffset(padapter, hwinfo, pHalData->bautoload_fail_flag);
+	hal_read_mac_hidden_rpt(padapter);
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("<==== _ReadEfuseInfo8703BS()\n"));
+}
+
+static void _ReadPROMContent(
+	IN PADAPTER 		padapter
+	)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+	u8			eeValue;
+
+	eeValue = rtw_read8(padapter, REG_9346CR);
+	// To check system boot selection.
+	pHalData->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? _TRUE : _FALSE;
+	pHalData->bautoload_fail_flag = (eeValue & EEPROM_EN) ? _FALSE : _TRUE;
+
+	RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
+		 ("%s: 9346CR=0x%02X, Boot from %s, Autoload %s\n",
+		  __FUNCTION__, eeValue,
+		  (pHalData->EepromOrEfuse ? "EEPROM" : "EFUSE"),
+		  (pHalData->bautoload_fail_flag ? "Fail" : "OK")));
+
+//	pHalData->EEType = IS_BOOT_FROM_EEPROM(Adapter) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE;
+
+	_ReadEfuseInfo8703BS(padapter);
+}
+
+static VOID
+_InitOtherVariable(
+	IN PADAPTER 		Adapter
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+
+
+	//if(Adapter->bInHctTest){
+	//	pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
+	//	pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
+	//	pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
+	//	pMgntInfo->keepAliveLevel = 0;
+	//}
+
+
+
+}
+
+//
+//	Description:
+//		Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
+//
+//	Assumption:
+//		PASSIVE_LEVEL (SDIO interface)
+//
+//
+static void ReadAdapterInfo8703BS(PADAPTER padapter)
+{
+    u8 val8;
+
+	val8 = rtw_read8(padapter, 0x4e);
+	MSG_8192C("%s, 0x4e=0x%x\n", __func__, val8);
+	val8 |= BIT(6);
+	rtw_write8(padapter, 0x4e, val8);
+
+	/* Read EEPROM size before call any EEPROM function */
+	padapter->EepromAddressSize = GetEEPROMSize8703B(padapter);
+
+	_EfuseCellSel(padapter);
+	_ReadRFType(padapter);
+	_ReadPROMContent(padapter);
+	_InitOtherVariable(padapter);
+
+#ifdef CONFIG_PLATFORM_INTEL_BYT
+{ //for BT, let BT can control ANT when wifi disable
+	u32 val32;
+	MSG_8192C("%s, 0x4c=0x%x\n", __func__, rtw_read32(padapter, 0x4c));
+	val32 = rtw_read32(padapter, 0x64);
+	MSG_8192C("%s, 0x64=0x%x\n", __func__, val32);
+	val32 |= BIT(13);
+	rtw_write32(padapter, 0x64, val32);
+	MSG_8192C("%s, 0x64=0x%x\n", __func__, rtw_read32(padapter, 0x64));
+}
+#endif //CONFIG_PLATFORM_INTEL_BYT
+
+	if (!rtw_is_hw_init_completed(padapter))
+		rtw_write8(padapter, 0x67, 0x00); // for BT, Switch Ant control to BT
+}
+
+/*
+ * If variable not handled here,
+ * some variables will be processed in SetHwReg8703B()
+ */
+void SetHwReg8703BS(PADAPTER padapter, u8 variable, u8 *val)
+{
+	PHAL_DATA_TYPE pHalData;
+	u8 val8;
+
+_func_enter_;
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	switch (variable)
+	{
+		case HW_VAR_SET_RPWM:
+			// rpwm value only use BIT0(clock bit) ,BIT6(Ack bit), and BIT7(Toggle bit)
+			// BIT0 value - 1: 32k, 0:40MHz.
+			// BIT6 value - 1: report cpwm value after success set, 0:do not report.
+			// BIT7 value - Toggle bit change.
+			{
+				val8 = *val;
+				val8 &= 0xC1;
+				rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8);
+			}
+			break;
+		case HW_VAR_SET_REQ_FW_PS:
+			//1. driver write 0x8f[4]=1  //request fw ps state (only can write bit4)
+			{
+				u8 req_fw_ps=0;
+				req_fw_ps = rtw_read8(padapter, 0x8f);
+				req_fw_ps |= 0x10;
+				rtw_write8(padapter, 0x8f, req_fw_ps);
+			}
+			break;
+		case HW_VAR_RXDMA_AGG_PG_TH:
+			val8 = *val;
+
+			// TH=1 => invalidate RX DMA aggregation
+			// TH=0 => validate RX DMA aggregation, use init value.
+			if (val8 == 0)
+			{
+				// enable RXDMA aggregation
+				//_RXAggrSwitch(padapter, _TRUE);
+			}
+			else
+			{
+				// disable RXDMA aggregation
+				//_RXAggrSwitch(padapter, _FALSE);
+			}
+			break;
+		case HW_VAR_DM_IN_LPS:
+			rtl8703b_hal_dm_in_lps(padapter);
+			break;
+		default:
+			SetHwReg8703B(padapter, variable, val);
+			break;
+	}
+
+_func_exit_;
+}
+
+/*
+ * If variable not handled here,
+ * some variables will be processed in GetHwReg8703B()
+ */
+void GetHwReg8703BS(PADAPTER padapter, u8 variable, u8 *val)
+{
+	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+_func_enter_;
+
+	switch (variable)
+	{
+		case HW_VAR_CPWM:
+			*val = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HCPWM1_8703B);
+			break;
+
+		case HW_VAR_FW_PS_STATE:
+			{
+				//3. read dword 0x88               //driver read fw ps state
+				*((u16*)val) = rtw_read16(padapter, 0x88);
+			}
+			break;
+		default:
+			GetHwReg8703B(padapter, variable, val);
+			break;
+	}
+
+_func_exit_;
+}
+
+//
+//	Description:
+//		Query setting of specified variable.
+//
+u8
+GetHalDefVar8703BSDIO(
+	IN	PADAPTER				Adapter,
+	IN	HAL_DEF_VARIABLE		eVariable,
+	IN	PVOID					pValue
+	)
+{
+	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
+	u8			bResult = _SUCCESS;
+
+	switch(eVariable)
+	{
+		case HAL_DEF_IS_SUPPORT_ANT_DIV:
+#ifdef CONFIG_ANTENNA_DIVERSITY
+			*((u8 *)pValue) = _FALSE;
+#endif
+			break;
+		case HAL_DEF_CURRENT_ANTENNA:
+#ifdef CONFIG_ANTENNA_DIVERSITY
+			*(( u8*)pValue) = pHalData->CurAntenna;
+#endif
+			break;
+		case HW_VAR_MAX_RX_AMPDU_FACTOR:
+			// Stanley@BB.SD3 suggests 16K can get stable performance
+			// coding by Lucas@20130730
+			*(HT_CAP_AMPDU_FACTOR*)pValue = MAX_AMPDU_FACTOR_16K;
+			break;
+		default:
+			bResult = GetHalDefVar8703B(Adapter, eVariable, pValue);
+			break;
+	}
+
+	return bResult;
+}
+
+//
+//	Description:
+//		Change default setting of specified variable.
+//
+u8
+SetHalDefVar8703BSDIO(
+	IN	PADAPTER				Adapter,
+	IN	HAL_DEF_VARIABLE		eVariable,
+	IN	PVOID					pValue
+	)
+{
+	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
+	u8			bResult = _SUCCESS;
+
+	switch(eVariable)
+	{
+		default:
+			bResult = SetHalDefVar8703B(Adapter, eVariable, pValue);
+			break;
+	}
+
+	return bResult;
+}
+
+void rtl8703bs_set_hal_ops(PADAPTER padapter)
+{
+	struct hal_ops *pHalFunc = &padapter->HalFunc;
+
+_func_enter_;
+
+	rtl8703b_set_hal_ops(pHalFunc);
+
+	pHalFunc->hal_power_on = &_InitPowerOn_8703BS;
+	pHalFunc->hal_power_off = &CardDisableRTL8703BSdio;
+
+
+	pHalFunc->hal_init = &rtl8703bs_hal_init;
+	pHalFunc->hal_deinit = &rtl8703bs_hal_deinit;
+
+	pHalFunc->init_xmit_priv = &rtl8703bs_init_xmit_priv;
+	pHalFunc->free_xmit_priv = &rtl8703bs_free_xmit_priv;
+
+	pHalFunc->init_recv_priv = &rtl8703bs_init_recv_priv;
+	pHalFunc->free_recv_priv = &rtl8703bs_free_recv_priv;
+
+	pHalFunc->InitSwLeds = &rtl8703bs_InitSwLeds;
+	pHalFunc->DeInitSwLeds = &rtl8703bs_DeInitSwLeds;
+
+	pHalFunc->init_default_value = &rtl8703bs_init_default_value;
+	pHalFunc->intf_chip_configure = &rtl8703bs_interface_configure;
+	pHalFunc->read_adapter_info = &ReadAdapterInfo8703BS;
+
+	pHalFunc->enable_interrupt = &EnableInterrupt8703BSdio;
+	pHalFunc->disable_interrupt = &DisableInterrupt8703BSdio;
+	pHalFunc->check_ips_status = &CheckIPSStatus;
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+	pHalFunc->clear_interrupt = &ClearInterrupt8703BSdio;
+#endif
+	pHalFunc->SetHwRegHandler = &SetHwReg8703BS;
+	pHalFunc->GetHwRegHandler = &GetHwReg8703BS;
+	pHalFunc->GetHalDefVarHandler = &GetHalDefVar8703BSDIO;
+ 	pHalFunc->SetHalDefVarHandler = &SetHalDefVar8703BSDIO;
+
+	pHalFunc->hal_xmit = &rtl8703bs_hal_xmit;
+	pHalFunc->mgnt_xmit = &rtl8703bs_mgnt_xmit;
+	pHalFunc->hal_xmitframe_enqueue = &rtl8703bs_hal_xmitframe_enqueue;
+
+#ifdef CONFIG_HOSTAPD_MLME
+	pHalFunc->hostap_mgnt_xmit_entry = NULL;
+#endif
+
+#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
+	pHalFunc->hal_init_checkbthang_workqueue = &rtl8703bs_init_checkbthang_workqueue;
+	pHalFunc->hal_free_checkbthang_workqueue = &rtl8703bs_free_checkbthang_workqueue;
+	pHalFunc->hal_cancle_checkbthang_workqueue = &rtl8703bs_cancle_checkbthang_workqueue;
+	pHalFunc->hal_checke_bt_hang = &rtl8703bs_hal_check_bt_hang;
+#endif
+
+_func_exit_;
+}
+
+
diff --git a/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c
new file mode 100644
index 000000000..9c2bf0a35
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c
@@ -0,0 +1,1813 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 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
+ *
+ *******************************************************************************/
+#define _SDIO_OPS_C_
+
+#include <rtl8703b_hal.h>
+
+//#define SDIO_DEBUG_IO 1
+
+
+//
+// Description:
+//	The following mapping is for SDIO host local register space.
+//
+// Creadted by Roger, 2011.01.31.
+//
+static void HalSdioGetCmdAddr8703BSdio(
+	IN	PADAPTER			padapter,
+	IN 	u8				DeviceID,
+	IN	u32				Addr,
+	OUT	u32*				pCmdAddr
+	)
+{
+	switch (DeviceID)
+	{
+		case SDIO_LOCAL_DEVICE_ID:
+			*pCmdAddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (Addr & SDIO_LOCAL_MSK));
+			break;
+
+		case WLAN_IOREG_DEVICE_ID:
+			*pCmdAddr = ((WLAN_IOREG_DEVICE_ID << 13) | (Addr & WLAN_IOREG_MSK));
+			break;
+
+		case WLAN_TX_HIQ_DEVICE_ID:
+			*pCmdAddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
+			break;
+
+		case WLAN_TX_MIQ_DEVICE_ID:
+			*pCmdAddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
+			break;
+
+		case WLAN_TX_LOQ_DEVICE_ID:
+			*pCmdAddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
+			break;
+
+		case WLAN_RX0FF_DEVICE_ID:
+			*pCmdAddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (Addr & WLAN_RX0FF_MSK));
+			break;
+
+		default:
+			break;
+	}
+}
+
+static u8 get_deviceid(u32 addr)
+{
+	u8 devideId;
+	u16 pseudoId;
+
+
+	pseudoId = (u16)(addr >> 16);
+	switch (pseudoId)
+	{
+		case 0x1025:
+			devideId = SDIO_LOCAL_DEVICE_ID;
+			break;
+
+		case 0x1026:
+			devideId = WLAN_IOREG_DEVICE_ID;
+			break;
+
+//		case 0x1027:
+//			devideId = SDIO_FIRMWARE_FIFO;
+//			break;
+
+		case 0x1031:
+			devideId = WLAN_TX_HIQ_DEVICE_ID;
+			break;
+
+		case 0x1032:
+			devideId = WLAN_TX_MIQ_DEVICE_ID;
+			break;
+
+		case 0x1033:
+			devideId = WLAN_TX_LOQ_DEVICE_ID;
+			break;
+
+		case 0x1034:
+			devideId = WLAN_RX0FF_DEVICE_ID;
+			break;
+
+		default:
+//			devideId = (u8)((addr >> 13) & 0xF);
+			devideId = WLAN_IOREG_DEVICE_ID;
+			break;
+	}
+
+	return devideId;
+}
+
+/*
+ * Ref:
+ *	HalSdioGetCmdAddr8703BSdio()
+ */
+static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset)
+{
+	u8 deviceId;
+	u16 offset;
+	u32 ftaddr;
+
+
+	deviceId = get_deviceid(addr);
+	offset = 0;
+
+	switch (deviceId)
+	{
+		case SDIO_LOCAL_DEVICE_ID:
+			offset = addr & SDIO_LOCAL_MSK;
+			break;
+
+		case WLAN_TX_HIQ_DEVICE_ID:
+		case WLAN_TX_MIQ_DEVICE_ID:
+		case WLAN_TX_LOQ_DEVICE_ID:
+			offset = addr & WLAN_FIFO_MSK;
+			break;
+
+		case WLAN_RX0FF_DEVICE_ID:
+			offset = addr & WLAN_RX0FF_MSK;
+			break;
+
+		case WLAN_IOREG_DEVICE_ID:
+		default:
+			deviceId = WLAN_IOREG_DEVICE_ID;
+			offset = addr & WLAN_IOREG_MSK;
+			break;
+	}
+	ftaddr = (deviceId << 13) | offset;
+
+	if (pdeviceId) *pdeviceId = deviceId;
+	if (poffset) *poffset = offset;
+
+	return ftaddr;
+}
+
+u8 sdio_read8(struct intf_hdl *pintfhdl, u32 addr)
+{
+	u32 ftaddr;
+	u8 val;
+
+_func_enter_;
+	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+	val = sd_read8(pintfhdl, ftaddr, NULL);
+
+_func_exit_;
+
+	return val;
+}
+
+u16 sdio_read16(struct intf_hdl *pintfhdl, u32 addr)
+{
+	u32 ftaddr;
+	u16 val;	
+
+_func_enter_;
+	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+	val = 0;
+	sd_cmd52_read(pintfhdl, ftaddr, 2, (u8*)&val);
+	val = le16_to_cpu(val);
+
+_func_exit_;
+
+	return val;
+}
+
+u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr)
+{
+	PADAPTER padapter;
+	u8 bMacPwrCtrlOn;
+	u8 deviceId;
+	u16 offset;
+	u32 ftaddr;
+	u8 shift;
+	u32 val;
+	s32 err;
+
+_func_enter_;
+
+	padapter = pintfhdl->padapter;
+	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+		|| (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
+#endif
+		)
+	{
+		val = 0;
+		err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8*)&val);
+#ifdef SDIO_DEBUG_IO
+		if (!err) {
+#endif
+			val = le32_to_cpu(val);
+			return val;
+#ifdef SDIO_DEBUG_IO
+		}
+
+		DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr);
+		return SDIO_ERR_VAL32;
+#endif
+	}
+
+	// 4 bytes alignment
+	shift = ftaddr & 0x3;
+	if (shift == 0) {
+		val = sd_read32(pintfhdl, ftaddr, NULL);
+	} else {
+		u8 *ptmpbuf;
+
+		ptmpbuf = (u8*)rtw_malloc(8);
+		if (NULL == ptmpbuf) {
+			DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size=8) addr=0x%x\n", __func__, addr);
+			return SDIO_ERR_VAL32;
+		}
+
+		ftaddr &= ~(u16)0x3;
+		sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
+		_rtw_memcpy(&val, ptmpbuf+shift, 4);
+		val = le32_to_cpu(val);
+
+		rtw_mfree(ptmpbuf, 8);
+	}
+
+_func_exit_;
+
+	return val;
+}
+
+s32 sdio_readN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf)
+{
+	PADAPTER padapter;
+	u8 bMacPwrCtrlOn;
+	u8 deviceId;
+	u16 offset;
+	u32 ftaddr;
+	u8 shift;
+	s32 err;
+
+_func_enter_;
+
+	padapter = pintfhdl->padapter;
+	err = 0;
+
+	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+		|| (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
+#endif
+		)
+	{
+		err = sd_cmd52_read(pintfhdl, ftaddr, cnt, pbuf);
+		return err;
+	}
+
+	// 4 bytes alignment
+	shift = ftaddr & 0x3;
+	if (shift == 0) {
+		err = sd_read(pintfhdl, ftaddr, cnt, pbuf);
+	} else {
+		u8 *ptmpbuf;
+		u32 n;
+
+		ftaddr &= ~(u16)0x3;
+		n = cnt + shift;
+		ptmpbuf = rtw_malloc(n);
+		if (NULL == ptmpbuf) return -1;
+		err = sd_read(pintfhdl, ftaddr, n, ptmpbuf);
+		if (!err)
+			_rtw_memcpy(pbuf, ptmpbuf+shift, cnt);
+		rtw_mfree(ptmpbuf, n);
+	}
+
+_func_exit_;
+
+	return err;
+}
+
+s32 sdio_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
+{
+	u32 ftaddr;
+	s32 err;
+
+_func_enter_;
+	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+	err = 0;
+	sd_write8(pintfhdl, ftaddr, val, &err);
+
+_func_exit_;
+
+	return err;
+}
+
+s32 sdio_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
+{
+	u32 ftaddr;
+	u8 shift;
+	s32 err;
+
+_func_enter_;
+	ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
+	val = cpu_to_le16(val);
+	err = sd_cmd52_write(pintfhdl, ftaddr, 2, (u8*)&val);
+
+_func_exit_;
+
+	return err;
+}
+
+s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
+{
+	PADAPTER padapter;
+	u8 bMacPwrCtrlOn;
+	u8 deviceId;
+	u16 offset;
+	u32 ftaddr;
+	u8 shift;
+	s32 err;
+
+_func_enter_;
+
+	padapter = pintfhdl->padapter;
+	err = 0;
+
+	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+		|| (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
+#endif
+		)
+	{
+		val = cpu_to_le32(val);
+		err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8*)&val);
+		return err;
+	}
+
+	// 4 bytes alignment
+	shift = ftaddr & 0x3;
+#if 1
+	if (shift == 0)
+	{
+		sd_write32(pintfhdl, ftaddr, val, &err);
+	}
+	else
+	{
+		val = cpu_to_le32(val);
+		err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8*)&val);
+	}
+#else
+	if (shift == 0) {
+		sd_write32(pintfhdl, ftaddr, val, &err);
+	} else {
+		u8 *ptmpbuf;
+
+		ptmpbuf = (u8*)rtw_malloc(8);
+		if (NULL == ptmpbuf) return (-1);
+
+		ftaddr &= ~(u16)0x3;
+		err = sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
+		if (err) {
+			rtw_mfree(ptmpbuf, 8);
+			return err;
+		}
+		val = cpu_to_le32(val);
+		_rtw_memcpy(ptmpbuf+shift, &val, 4);
+		err = sd_write(pintfhdl, ftaddr, 8, ptmpbuf);
+
+		rtw_mfree(ptmpbuf, 8);
+	}
+#endif
+
+_func_exit_;
+
+	return err;
+}
+
+s32 sdio_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8* pbuf)
+{
+	PADAPTER padapter;
+	u8 bMacPwrCtrlOn;
+	u8 deviceId;
+	u16 offset;
+	u32 ftaddr;
+	u8 shift;
+	s32 err;
+
+_func_enter_;
+
+	padapter = pintfhdl->padapter;
+	err = 0;
+
+	ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
+		|| (_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
+#endif
+		)
+	{
+		err = sd_cmd52_write(pintfhdl, ftaddr, cnt, pbuf);
+		return err;
+	}
+
+	shift = ftaddr & 0x3;
+	if (shift == 0) {
+		err = sd_write(pintfhdl, ftaddr, cnt, pbuf);
+	} else {
+		u8 *ptmpbuf;
+		u32 n;
+
+		ftaddr &= ~(u16)0x3;
+		n = cnt + shift;
+		ptmpbuf = rtw_malloc(n);
+		if (NULL == ptmpbuf) return -1;
+		err = sd_read(pintfhdl, ftaddr, 4, ptmpbuf);
+		if (err) {
+			rtw_mfree(ptmpbuf, n);
+			return err;
+		}
+		_rtw_memcpy(ptmpbuf+shift, pbuf, cnt);
+		err = sd_write(pintfhdl, ftaddr, n, ptmpbuf);
+		rtw_mfree(ptmpbuf, n);
+	}
+
+_func_exit_;
+
+	return err;
+}
+
+u8 sdio_f0_read8(struct intf_hdl *pintfhdl, u32 addr)
+{
+	u32 ftaddr;
+	u8 val;
+
+_func_enter_;
+	val = sd_f0_read8(pintfhdl, addr, NULL);
+
+_func_exit_;
+
+	return val;
+}
+
+void sdio_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
+{
+	s32 err;
+
+_func_enter_;
+
+	err = sdio_readN(pintfhdl, addr, cnt, rmem);
+
+_func_exit_;
+}
+
+void sdio_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
+{
+_func_enter_;
+
+	sdio_writeN(pintfhdl, addr, cnt, wmem);
+
+_func_exit_;
+}
+
+/*
+ * Description:
+ *	Read from RX FIFO
+ *	Round read size to block size,
+ *	and make sure data transfer will be done in one command.
+ *
+ * Parameters:
+ *	pintfhdl	a pointer of intf_hdl
+ *	addr		port ID
+ *	cnt			size to read
+ *	rmem		address to put data
+ *
+ * Return:
+ *	_SUCCESS(1)		Success
+ *	_FAIL(0)		Fail
+ */
+static u32 sdio_read_port(
+	struct intf_hdl *pintfhdl,
+	u32 addr,
+	u32 cnt,
+	u8 *mem)
+{
+	PADAPTER padapter;
+	PSDIO_DATA psdio;
+	PHAL_DATA_TYPE phal;
+	u32 oldcnt;
+#ifdef SDIO_DYNAMIC_ALLOC_MEM
+	u8 *oldmem;
+#endif
+	s32 err;
+
+
+	padapter = pintfhdl->padapter;
+	psdio = &adapter_to_dvobj(padapter)->intf_data;
+	phal = GET_HAL_DATA(padapter);
+
+	HalSdioGetCmdAddr8703BSdio(padapter, addr, phal->SdioRxFIFOCnt++, &addr);
+
+	oldcnt = cnt;
+	if (cnt > psdio->block_transfer_len)
+		cnt = _RND(cnt, psdio->block_transfer_len);
+//	cnt = sdio_align_size(cnt);
+
+	if (oldcnt != cnt) {
+#ifdef SDIO_DYNAMIC_ALLOC_MEM
+		oldmem = mem;
+		mem = rtw_malloc(cnt);
+		if (mem == NULL) {
+			DBG_8192C(KERN_WARNING "%s: allocate memory %d bytes fail!\n", __func__, cnt);
+			mem = oldmem;
+			oldmem == NULL;
+		}
+#else
+		// in this case, caller should gurante the buffer is big enough
+		// to receive data after alignment
+#endif
+	}
+
+	err = _sd_read(pintfhdl, addr, cnt, mem);
+
+#ifdef SDIO_DYNAMIC_ALLOC_MEM
+	if ((oldcnt != cnt) && (oldmem)) {
+		_rtw_memcpy(oldmem, mem, oldcnt);
+		rtw_mfree(mem, cnt);
+	}
+#endif
+
+	if (err) return _FAIL;
+	return _SUCCESS;
+}
+
+/*
+ * Description:
+ *	Write to TX FIFO
+ *	Align write size block size,
+ *	and make sure data could be written in one command.
+ *
+ * Parameters:
+ *	pintfhdl	a pointer of intf_hdl
+ *	addr		port ID
+ *	cnt			size to write
+ *	wmem		data pointer to write
+ *
+ * Return:
+ *	_SUCCESS(1)		Success
+ *	_FAIL(0)		Fail
+ */
+static u32 sdio_write_port(
+	struct intf_hdl *pintfhdl,
+	u32 addr,
+	u32 cnt,
+	u8 *mem)
+{
+	PADAPTER padapter;
+	PSDIO_DATA psdio;
+	s32 err;
+	struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
+
+	padapter = pintfhdl->padapter;
+	psdio = &adapter_to_dvobj(padapter)->intf_data;
+
+	if (!rtw_is_hw_init_completed(padapter)) {
+		DBG_871X("%s [addr=0x%x cnt=%d] padapter->hw_init_completed == _FALSE\n",__func__,addr,cnt);
+		return _FAIL;
+	}
+
+	cnt = _RND4(cnt);
+	HalSdioGetCmdAddr8703BSdio(padapter, addr, cnt >> 2, &addr);
+
+	if (cnt > psdio->block_transfer_len)
+		cnt = _RND(cnt, psdio->block_transfer_len);
+//	cnt = sdio_align_size(cnt);
+
+	err = sd_write(pintfhdl, addr, cnt, xmitbuf->pdata);
+
+	rtw_sctx_done_err(&xmitbuf->sctx,
+		err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
+
+	if (err) return _FAIL;
+	return _SUCCESS;
+}
+
+void sdio_set_intf_ops(_adapter *padapter, struct _io_ops *pops)
+{
+_func_enter_;
+
+	pops->_read8 = &sdio_read8;
+	pops->_read16 = &sdio_read16;
+	pops->_read32 = &sdio_read32;
+	pops->_read_mem = &sdio_read_mem;
+	pops->_read_port = &sdio_read_port;
+
+	pops->_write8 = &sdio_write8;
+	pops->_write16 = &sdio_write16;
+	pops->_write32 = &sdio_write32;
+	pops->_writeN = &sdio_writeN;
+	pops->_write_mem = &sdio_write_mem;
+	pops->_write_port = &sdio_write_port;
+
+	pops->_sd_f0_read8 = sdio_f0_read8;
+
+_func_exit_;
+}
+
+/*
+ * Todo: align address to 4 bytes.
+ */
+s32 _sdio_local_read(
+	PADAPTER	padapter,
+	u32			addr,
+	u32			cnt,
+	u8			*pbuf)
+{
+	struct intf_hdl * pintfhdl;
+	u8 bMacPwrCtrlOn;
+	s32 err;
+	u8 *ptmpbuf;
+	u32 n;
+
+
+	pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if (_FALSE == bMacPwrCtrlOn)
+	{
+		err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
+		return err;
+	}
+
+	n = RND4(cnt);
+	ptmpbuf = (u8*)rtw_malloc(n);
+	if (!ptmpbuf)
+		return (-1);
+
+	err = _sd_read(pintfhdl, addr, n, ptmpbuf);
+	if (!err)
+		_rtw_memcpy(pbuf, ptmpbuf, cnt);
+
+	if (ptmpbuf)
+		rtw_mfree(ptmpbuf, n);
+
+	return err;
+}
+
+/*
+ * Todo: align address to 4 bytes.
+ */
+s32 sdio_local_read(
+	PADAPTER	padapter,
+	u32			addr,
+	u32			cnt,
+	u8			*pbuf)
+{
+	struct intf_hdl * pintfhdl;
+	u8 bMacPwrCtrlOn;
+	s32 err;
+	u8 *ptmpbuf;
+	u32 n;
+
+	pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
+#endif
+		)
+	{
+		err = sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
+		return err;
+	}
+
+	n = RND4(cnt);
+	ptmpbuf = (u8*)rtw_malloc(n);
+	if (!ptmpbuf)
+		return (-1);
+
+	err = sd_read(pintfhdl, addr, n, ptmpbuf);
+	if (!err)
+		_rtw_memcpy(pbuf, ptmpbuf, cnt);
+
+	if (ptmpbuf)
+		rtw_mfree(ptmpbuf, n);
+
+	return err;
+}
+
+/*
+ * Todo: align address to 4 bytes.
+ */
+s32 _sdio_local_write(
+	PADAPTER	padapter,
+	u32			addr,
+	u32			cnt,
+	u8			*pbuf)
+{
+	struct intf_hdl * pintfhdl;
+	u8 bMacPwrCtrlOn;
+	s32 err;
+	u8 *ptmpbuf;
+
+	if(addr & 0x3)
+		DBG_8192C("%s, address must be 4 bytes alignment\n", __FUNCTION__);
+
+	if(cnt  & 0x3)
+		DBG_8192C("%s, size must be the multiple of 4 \n", __FUNCTION__);
+
+	pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
+#endif
+		)
+	{
+		err = _sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
+		return err;
+	}
+
+	ptmpbuf = (u8*)rtw_malloc(cnt);
+	if (!ptmpbuf)
+		return (-1);
+
+	_rtw_memcpy(ptmpbuf, pbuf, cnt);
+
+	err = _sd_write(pintfhdl, addr, cnt, ptmpbuf);
+
+	if (ptmpbuf)
+		rtw_mfree(ptmpbuf, cnt);
+
+	return err;
+}
+
+/*
+ * Todo: align address to 4 bytes.
+ */
+s32 sdio_local_write(
+	PADAPTER	padapter,
+	u32		addr,
+	u32		cnt,
+	u8		*pbuf)
+{
+	struct intf_hdl * pintfhdl;
+	u8 bMacPwrCtrlOn;
+	s32 err;
+	u8 *ptmpbuf;
+
+	if(addr & 0x3)
+		DBG_8192C("%s, address must be 4 bytes alignment\n", __FUNCTION__);
+
+	if(cnt  & 0x3)
+		DBG_8192C("%s, size must be the multiple of 4 \n", __FUNCTION__);
+
+	pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
+#endif
+		)
+	{
+		err = sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
+		return err;
+	}
+
+	ptmpbuf = (u8*)rtw_malloc(cnt);
+	if (!ptmpbuf)
+		return (-1);
+
+	_rtw_memcpy(ptmpbuf, pbuf, cnt);
+
+	err = sd_write(pintfhdl, addr, cnt, ptmpbuf);
+
+	if (ptmpbuf)
+		rtw_mfree(ptmpbuf, cnt);
+
+	return err;
+}
+
+u8 SdioLocalCmd52Read1Byte(PADAPTER padapter, u32 addr)
+{	
+	u8 val = 0;
+	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+	sd_cmd52_read(pintfhdl, addr, 1, &val);
+
+	return val;
+}
+
+u16 SdioLocalCmd52Read2Byte(PADAPTER padapter, u32 addr)
+{	
+	u16 val = 0;
+	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+	sd_cmd52_read(pintfhdl, addr, 2, (u8*)&val);
+
+	val = le16_to_cpu(val);
+
+	return val;
+}
+
+u32 SdioLocalCmd52Read4Byte(PADAPTER padapter, u32 addr)
+{	
+	u32 val = 0;
+	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+	sd_cmd52_read(pintfhdl, addr, 4, (u8*)&val);
+
+	val = le32_to_cpu(val);
+
+	return val;
+}
+
+u32 SdioLocalCmd53Read4Byte(PADAPTER padapter, u32 addr)
+{
+	
+	u8 bMacPwrCtrlOn;
+	u32 val = 0;
+	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+	bMacPwrCtrlOn = _FALSE;
+	rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+	if ((_FALSE == bMacPwrCtrlOn)
+#ifdef CONFIG_LPS_LCLK
+		|| (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
+#endif
+		)
+	{
+		sd_cmd52_read(pintfhdl, addr, 4, (u8*)&val);
+		val = le32_to_cpu(val);
+	}
+	else
+		val = sd_read32(pintfhdl, addr, NULL);
+
+	return val;
+}
+
+void SdioLocalCmd52Write1Byte(PADAPTER padapter, u32 addr, u8 v)
+{
+	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+	sd_cmd52_write(pintfhdl, addr, 1, &v);
+}
+
+void SdioLocalCmd52Write2Byte(PADAPTER padapter, u32 addr, u16 v)
+{
+	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
+
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+	v = cpu_to_le16(v);
+	sd_cmd52_write(pintfhdl, addr, 2, (u8*)&v);
+}
+
+void SdioLocalCmd52Write4Byte(PADAPTER padapter, u32 addr, u32 v)
+{
+	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
+	HalSdioGetCmdAddr8703BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
+	v = cpu_to_le32(v);
+	sd_cmd52_write(pintfhdl, addr, 4, (u8*)&v);
+}
+
+#if 0
+void
+DumpLoggedInterruptHistory8703Sdio(
+	PADAPTER		padapter
+)
+{
+	HAL_DATA_TYPE	*pHalData=GET_HAL_DATA(padapter);
+	u4Byte				DebugLevel = DBG_LOUD;
+
+	if (DBG_Var.DbgPrintIsr == 0)
+		return;
+
+	DBG_ChkDrvResource(padapter);
+
+
+	if(pHalData->InterruptLog.nISR_RX_REQUEST)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RX_REQUEST[%ld]\t\n", pHalData->InterruptLog.nISR_RX_REQUEST));
+
+	if(pHalData->InterruptLog.nISR_AVAL)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# AVAL[%ld]\t\n", pHalData->InterruptLog.nISR_AVAL));
+
+	if(pHalData->InterruptLog.nISR_TXERR)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXERR[%ld]\t\n", pHalData->InterruptLog.nISR_TXERR));
+
+	if(pHalData->InterruptLog.nISR_RXERR)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RXERR[%ld]\t\n", pHalData->InterruptLog.nISR_RXERR));
+
+	if(pHalData->InterruptLog.nISR_TXFOVW)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXFOVW[%ld]\t\n", pHalData->InterruptLog.nISR_TXFOVW));
+
+	if(pHalData->InterruptLog.nISR_RXFOVW)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RXFOVW[%ld]\t\n", pHalData->InterruptLog.nISR_RXFOVW));
+
+	if(pHalData->InterruptLog.nISR_TXBCNOK)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXBCNOK[%ld]\t\n", pHalData->InterruptLog.nISR_TXBCNOK));
+
+	if(pHalData->InterruptLog.nISR_TXBCNERR)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXBCNERR[%ld]\t\n", pHalData->InterruptLog.nISR_TXBCNERR));
+
+	if(pHalData->InterruptLog.nISR_BCNERLY_INT)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# BCNERLY_INT[%ld]\t\n", pHalData->InterruptLog.nISR_BCNERLY_INT));
+
+	if(pHalData->InterruptLog.nISR_C2HCMD)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# C2HCMD[%ld]\t\n", pHalData->InterruptLog.nISR_C2HCMD));
+
+	if(pHalData->InterruptLog.nISR_CPWM1)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CPWM1L[%ld]\t\n", pHalData->InterruptLog.nISR_CPWM1));
+
+	if(pHalData->InterruptLog.nISR_CPWM2)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CPWM2[%ld]\t\n", pHalData->InterruptLog.nISR_CPWM2));
+
+	if(pHalData->InterruptLog.nISR_HSISR_IND)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# HSISR_IND[%ld]\t\n", pHalData->InterruptLog.nISR_HSISR_IND));
+
+	if(pHalData->InterruptLog.nISR_GTINT3_IND)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# GTINT3_IND[%ld]\t\n", pHalData->InterruptLog.nISR_GTINT3_IND));
+
+	if(pHalData->InterruptLog.nISR_GTINT4_IND)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# GTINT4_IND[%ld]\t\n", pHalData->InterruptLog.nISR_GTINT4_IND));
+
+	if(pHalData->InterruptLog.nISR_PSTIMEOUT)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# PSTIMEOUT[%ld]\t\n", pHalData->InterruptLog.nISR_PSTIMEOUT));
+
+	if(pHalData->InterruptLog.nISR_OCPINT)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# OCPINT[%ld]\t\n", pHalData->InterruptLog.nISR_OCPINT));
+
+	if(pHalData->InterruptLog.nISR_ATIMEND)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# ATIMEND[%ld]\t\n", pHalData->InterruptLog.nISR_ATIMEND));
+
+	if(pHalData->InterruptLog.nISR_ATIMEND_E)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# ATIMEND_E[%ld]\t\n", pHalData->InterruptLog.nISR_ATIMEND_E));
+
+	if(pHalData->InterruptLog.nISR_CTWEND)
+		RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CTWEND[%ld]\t\n", pHalData->InterruptLog.nISR_CTWEND));
+}
+
+void
+LogInterruptHistory8703Sdio(
+	PADAPTER			padapter,
+	PRT_ISR_CONTENT	pIsrContent
+)
+{
+	HAL_DATA_TYPE	*pHalData=GET_HAL_DATA(padapter);
+
+	if((pHalData->IntrMask[0] & SDIO_HIMR_RX_REQUEST_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_RX_REQUEST))
+		pHalData->InterruptLog.nISR_RX_REQUEST ++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_AVAL_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_AVAL))
+		pHalData->InterruptLog.nISR_AVAL++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_TXERR_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_TXERR))
+		pHalData->InterruptLog.nISR_TXERR++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_RXERR_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_RXERR))
+		pHalData->InterruptLog.nISR_RXERR++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_TXFOVW_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_TXFOVW))
+		pHalData->InterruptLog.nISR_TXFOVW++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_RXFOVW_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_RXFOVW))
+		pHalData->InterruptLog.nISR_RXFOVW++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_TXBCNOK_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_TXBCNOK))
+		pHalData->InterruptLog.nISR_TXBCNOK++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_TXBCNERR_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_TXBCNERR))
+		pHalData->InterruptLog.nISR_TXBCNERR++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_BCNERLY_INT_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_BCNERLY_INT))
+		pHalData->InterruptLog.nISR_BCNERLY_INT ++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_C2HCMD_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_C2HCMD))
+		pHalData->InterruptLog.nISR_C2HCMD++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_CPWM1_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_CPWM1))
+		pHalData->InterruptLog.nISR_CPWM1++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_CPWM2_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_CPWM2))
+		pHalData->InterruptLog.nISR_CPWM2++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_HSISR_IND_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_HSISR_IND))
+		pHalData->InterruptLog.nISR_HSISR_IND++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_GTINT3_IND_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_GTINT3_IND))
+		pHalData->InterruptLog.nISR_GTINT3_IND++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_GTINT4_IND_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_GTINT4_IND))
+		pHalData->InterruptLog.nISR_GTINT4_IND++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_PSTIMEOUT_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_PSTIMEOUT))
+		pHalData->InterruptLog.nISR_PSTIMEOUT++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_OCPINT_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_OCPINT))
+		pHalData->InterruptLog.nISR_OCPINT++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_ATIMEND_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_ATIMEND))
+		pHalData->InterruptLog.nISR_ATIMEND++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_ATIMEND_E_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_ATIMEND_E))
+		pHalData->InterruptLog.nISR_ATIMEND_E++;
+	if((pHalData->IntrMask[0] & SDIO_HIMR_CTWEND_MSK) &&
+		(pIsrContent->IntArray[0] & SDIO_HISR_CTWEND))
+		pHalData->InterruptLog.nISR_CTWEND++;
+
+}
+
+void
+DumpHardwareProfile8703Sdio(
+	IN	PADAPTER		padapter
+)
+{
+	DumpLoggedInterruptHistory8703Sdio(padapter);
+}
+#endif
+
+static s32 ReadInterrupt8703BSdio(PADAPTER padapter, u32 *phisr)
+{
+	u32 hisr, himr;
+	u8 val8, hisr_len;
+
+
+	if (phisr == NULL)
+		return _FALSE;
+
+	himr = GET_HAL_DATA(padapter)->sdio_himr;
+
+	// decide how many bytes need to be read
+	hisr_len = 0;
+	while (himr)
+	{
+		hisr_len++;
+		himr >>= 8;
+	}
+
+	hisr = 0;
+	while (hisr_len != 0)
+	{
+		hisr_len--;
+		val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR+hisr_len);
+		hisr |= (val8 << (8*hisr_len));
+	}
+
+	*phisr = hisr;
+
+	return _TRUE;
+}
+
+//
+//	Description:
+//		Initialize SDIO Host Interrupt Mask configuration variables for future use.
+//
+//	Assumption:
+//		Using SDIO Local register ONLY for configuration.
+//
+//	Created by Roger, 2011.02.11.
+//
+void InitInterrupt8703BSdio(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+	pHalData->sdio_himr = (u32)(			\
+								SDIO_HIMR_RX_REQUEST_MSK			|
+#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
+								SDIO_HIMR_AVAL_MSK					|
+#endif
+//								SDIO_HIMR_TXERR_MSK				|
+//								SDIO_HIMR_RXERR_MSK				|
+//								SDIO_HIMR_TXFOVW_MSK				|
+//								SDIO_HIMR_RXFOVW_MSK				|
+//								SDIO_HIMR_TXBCNOK_MSK				|
+//								SDIO_HIMR_TXBCNERR_MSK			|
+//								SDIO_HIMR_BCNERLY_INT_MSK			|
+//								SDIO_HIMR_C2HCMD_MSK				|
+#if defined(CONFIG_LPS_LCLK) && !defined(CONFIG_DETECT_CPWM_BY_POLLING)
+								SDIO_HIMR_CPWM1_MSK				|
+//								SDIO_HIMR_CPWM2_MSK				|
+#endif // CONFIG_LPS_LCLK && !CONFIG_DETECT_CPWM_BY_POLLING
+//								SDIO_HIMR_HSISR_IND_MSK			|
+//								SDIO_HIMR_GTINT3_IND_MSK			|
+//								SDIO_HIMR_GTINT4_IND_MSK			|
+//								SDIO_HIMR_PSTIMEOUT_MSK			|
+//								SDIO_HIMR_OCPINT_MSK				|
+//								SDIO_HIMR_ATIMEND_MSK				|
+//								SDIO_HIMR_ATIMEND_E_MSK			|
+//								SDIO_HIMR_CTWEND_MSK				|
+								0);
+}
+
+//
+//	Description:
+//		Initialize System Host Interrupt Mask configuration variables for future use.
+//
+//	Created by Roger, 2011.08.03.
+//
+void InitSysInterrupt8703BSdio(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	pHalData->SysIntrMask = (			\
+//							HSIMR_GPIO12_0_INT_EN			|
+//							HSIMR_SPS_OCP_INT_EN			|
+//							HSIMR_RON_INT_EN				|
+//							HSIMR_PDNINT_EN				|
+//							HSIMR_GPIO9_INT_EN				|
+							0);
+}
+
+#ifdef CONFIG_WOWLAN
+//
+//	Description:
+//		Clear corresponding SDIO Host ISR interrupt service.
+//
+//	Assumption:
+//		Using SDIO Local register ONLY for configuration.
+//
+//	Created by Roger, 2011.02.11.
+//
+void ClearInterrupt8703BSdio(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	u8 *clear;
+
+
+	if (rtw_is_surprise_removed(padapter))
+		return;
+
+	pHalData = GET_HAL_DATA(padapter);
+	clear = rtw_zmalloc(4);
+
+	// Clear corresponding HISR Content if needed
+	*(u32*)clear = cpu_to_le32(pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR);
+	if (*(u32*)clear)
+	{
+		// Perform write one clear operation
+		sdio_local_write(padapter, SDIO_REG_HISR, 4, clear);
+	}
+
+	rtw_mfree(clear, 4);
+}
+#endif
+
+//
+//	Description:
+//		Clear corresponding system Host ISR interrupt service.
+//
+//
+//	Created by Roger, 2011.02.11.
+//
+void ClearSysInterrupt8703BSdio(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	u32 clear;
+
+
+	if (rtw_is_surprise_removed(padapter))
+		return;
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	// Clear corresponding HISR Content if needed
+	clear = pHalData->SysIntrStatus & MASK_HSISR_CLEAR;
+	if (clear)
+	{
+		// Perform write one clear operation
+		rtw_write32(padapter, REG_HSISR, clear);
+	}
+}
+
+//
+//	Description:
+//		Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain.
+//
+//	Assumption:
+//		1. Using SDIO Local register ONLY for configuration.
+//		2. PASSIVE LEVEL
+//
+//	Created by Roger, 2011.02.11.
+//
+void EnableInterrupt8703BSdio(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE pHalData;
+	u32 himr;
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	himr = cpu_to_le32(pHalData->sdio_himr);
+	sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr);
+
+	RT_TRACE(_module_hci_ops_c_, _drv_notice_,
+		("%s: enable SDIO HIMR=0x%08X\n", __FUNCTION__, pHalData->sdio_himr));
+
+	// Update current system IMR settings
+	himr = rtw_read32(padapter, REG_HSIMR);
+	rtw_write32(padapter, REG_HSIMR, himr|pHalData->SysIntrMask);
+
+	RT_TRACE(_module_hci_ops_c_, _drv_notice_,
+		("%s: enable HSIMR=0x%08X\n", __FUNCTION__, pHalData->SysIntrMask));
+
+	//
+	// <Roger_Notes> 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.
+	// 2011.10.19.
+	//
+	rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
+}
+
+//
+//	Description:
+//		Disable SDIO Host IMR configuration to mask unnecessary interrupt service.
+//
+//	Assumption:
+//		Using SDIO Local register ONLY for configuration.
+//
+//	Created by Roger, 2011.02.11.
+//
+void DisableInterrupt8703BSdio(PADAPTER padapter)
+{
+	u32 himr;
+
+	himr = cpu_to_le32(SDIO_HIMR_DISABLED);
+	sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr);
+
+}
+
+//
+//	Description:
+//		Using 0x100 to check the power status of FW.
+//
+//	Assumption:
+//		Using SDIO Local register ONLY for configuration.
+//
+//	Created by Isaac, 2013.09.10.
+//
+u8 CheckIPSStatus(PADAPTER padapter)
+{
+	DBG_871X("%s(): Read 0x100=0x%02x 0x86=0x%02x\n", __func__,
+		rtw_read8(padapter, 0x100),rtw_read8(padapter, 0x86));
+	
+	if (rtw_read8(padapter, 0x100) == 0xEA)
+		return _TRUE;
+	else
+		return _FALSE;
+}
+
+#ifdef CONFIG_WOWLAN
+void DisableInterruptButCpwm28703BSdio(PADAPTER padapter)
+{
+	u32 himr, tmp;
+
+	sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
+	DBG_871X("DisableInterruptButCpwm28703BSdio(): Read SDIO_REG_HIMR: 0x%08x\n", tmp);
+	
+	himr = cpu_to_le32(SDIO_HIMR_DISABLED)|SDIO_HIMR_CPWM2_MSK;
+	sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr);
+
+	sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
+	DBG_871X("DisableInterruptButCpwm28703BSdio(): Read again SDIO_REG_HIMR: 0x%08x\n", tmp);
+}
+#endif //CONFIG_WOWLAN
+//
+//	Description:
+//		Update SDIO Host Interrupt Mask configuration on SDIO local domain.
+//
+//	Assumption:
+//		1. Using SDIO Local register ONLY for configuration.
+//		2. PASSIVE LEVEL
+//
+//	Created by Roger, 2011.02.11.
+//
+void UpdateInterruptMask8703BSdio(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR)
+{
+	HAL_DATA_TYPE *pHalData;
+
+	pHalData = GET_HAL_DATA(padapter);
+
+	if (AddMSR)
+		pHalData->sdio_himr |= AddMSR;
+
+	if (RemoveMSR)
+		pHalData->sdio_himr &= (~RemoveMSR);
+
+	DisableInterrupt8703BSdio(padapter);
+	EnableInterrupt8703BSdio(padapter);
+}
+
+#ifdef CONFIG_MAC_LOOPBACK_DRIVER
+static void sd_recv_loopback(PADAPTER padapter, u32 size)
+{
+	PLOOPBACKDATA ploopback;
+	u32 readsize, allocsize;
+	u8 *preadbuf;
+
+
+	readsize = size;
+	DBG_8192C("%s: read size=%d\n", __func__, readsize);
+	allocsize = _RND(readsize, adapter_to_dvobj(padapter)->intf_data.block_transfer_len);
+
+	ploopback = padapter->ploopback;
+	if (ploopback) {
+		ploopback->rxsize = readsize;
+		preadbuf = ploopback->rxbuf;
+	}
+	else {
+		preadbuf = rtw_malloc(allocsize);
+		if (preadbuf == NULL) {
+			DBG_8192C("%s: malloc fail size=%d\n", __func__, allocsize);
+			return;
+		}
+	}
+
+//	rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+	sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+
+	if (ploopback)
+		_rtw_up_sema(&ploopback->sema);
+	else {
+		u32 i;
+
+		DBG_8192C("%s: drop pkt\n", __func__);
+		for (i = 0; i < readsize; i+=4) {
+			DBG_8192C("%08X", *(u32*)(preadbuf + i));
+			if ((i+4) & 0x1F) printk(" ");
+			else printk("\n");
+		}
+		printk("\n");
+		rtw_mfree(preadbuf, allocsize);
+	}
+}
+#endif // CONFIG_MAC_LOOPBACK_DRIVER
+
+#ifdef CONFIG_SDIO_RX_COPY
+static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size)
+{
+	u32 readsize, ret;
+	u8 *preadbuf;
+	struct recv_priv *precvpriv;
+	struct recv_buf	*precvbuf;
+
+
+#if 0
+	readsize = size;
+#else
+	// Patch for some SDIO Host 4 bytes issue
+	// ex. RK3188
+	readsize = RND4(size);
+#endif
+
+	//3 1. alloc recvbuf
+	precvpriv = &padapter->recvpriv;
+	precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
+	if (precvbuf == NULL) {
+		DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __FUNCTION__);
+		return NULL;
+	}
+
+	//3 2. alloc skb
+	if (precvbuf->pskb == NULL) {
+		SIZE_PTR tmpaddr=0;
+		SIZE_PTR alignment=0;
+
+		precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
+		if (precvbuf->pskb == NULL) {
+			DBG_871X("%s: alloc_skb fail! read=%d\n", __FUNCTION__, readsize);
+			rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
+			return NULL;
+		}
+
+		precvbuf->pskb->dev = padapter->pnetdev;
+
+		tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
+		alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
+		skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
+	}
+
+	//3 3. read data from rxfifo
+	preadbuf = precvbuf->pskb->data;
+//	rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+	ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+	if (ret == _FAIL) {
+		RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __FUNCTION__));
+		rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
+		return NULL;
+	}
+
+	//3 4. init recvbuf
+	precvbuf->len = size;
+	precvbuf->phead = precvbuf->pskb->head;
+	precvbuf->pdata = precvbuf->pskb->data;
+	skb_set_tail_pointer(precvbuf->pskb, size);
+	precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+	precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+
+	return precvbuf;
+}
+#else // !CONFIG_SDIO_RX_COPY
+static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size)
+{
+	u32 sdioblksize, readsize, allocsize, ret;
+	u8 *preadbuf;
+	_pkt *ppkt;
+	struct recv_priv *precvpriv;
+	struct recv_buf	*precvbuf;
+
+
+	sdioblksize = adapter_to_dvobj(padapter)->intf_data.block_transfer_len;
+#if 0
+	readsize = size;
+#else
+	// Patch for some SDIO Host 4 bytes issue
+	// ex. RK3188
+	readsize = RND4(size);
+#endif
+
+	//3 1. alloc skb
+	// align to block size
+	if (readsize > sdioblksize)
+		allocsize = _RND(readsize, sdioblksize);
+	else
+		allocsize = readsize;
+
+	ppkt = rtw_skb_alloc(allocsize);
+
+	if (ppkt == NULL) {
+		RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: alloc_skb fail! alloc=%d read=%d\n", __FUNCTION__, allocsize, readsize));
+		return NULL;
+	}
+
+	//3 2. read data from rxfifo
+	preadbuf = skb_put(ppkt, size);
+//	rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+	ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
+	if (ret == _FAIL) {
+		rtw_skb_free(ppkt);
+		RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __FUNCTION__));
+		return NULL;
+	}
+
+	//3 3. alloc recvbuf
+	precvpriv = &padapter->recvpriv;
+	precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
+	if (precvbuf == NULL) {
+		rtw_skb_free(ppkt);
+		DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __FUNCTION__);
+		return NULL;
+	}
+
+	//3 4. init recvbuf
+	precvbuf->pskb = ppkt;
+
+	precvbuf->len = ppkt->len;
+
+	precvbuf->phead = ppkt->head;
+	precvbuf->pdata = ppkt->data;
+	precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+	precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+
+	return precvbuf;
+}
+#endif // !CONFIG_SDIO_RX_COPY
+
+static void sd_rxhandler(PADAPTER padapter, struct recv_buf *precvbuf)
+{
+	struct recv_priv *precvpriv;
+	_queue *ppending_queue;
+
+
+	precvpriv = &padapter->recvpriv;
+	ppending_queue = &precvpriv->recv_buf_pending_queue;
+
+	//3 1. enqueue recvbuf
+	rtw_enqueue_recvbuf(precvbuf, ppending_queue);
+
+	//3 2. schedule tasklet
+#ifdef PLATFORM_LINUX
+	tasklet_schedule(&precvpriv->recv_tasklet);
+#endif
+}
+
+void sd_int_dpc(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE phal;
+	struct dvobj_priv *dvobj;
+	struct intf_hdl * pintfhdl=&padapter->iopriv.intf;
+	struct pwrctrl_priv *pwrctl;
+
+
+	phal = GET_HAL_DATA(padapter);
+	dvobj = adapter_to_dvobj(padapter);
+	pwrctl = dvobj_to_pwrctl(dvobj);
+
+#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
+	if (phal->sdio_hisr & SDIO_HISR_AVAL)
+	{
+		//_irqL irql;
+		u8	freepage[4];
+
+		_sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage);
+		//_enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
+		//_rtw_memcpy(phal->SdioTxFIFOFreePage, freepage, 4);
+		//_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
+		//DBG_871X("SDIO_HISR_AVAL, Tx Free Page = 0x%x%x%x%x\n",
+		//	freepage[0],
+		//	freepage[1],
+		//	freepage[2],
+		//	freepage[3]);
+		_rtw_up_sema(&(padapter->xmitpriv.xmit_sema));
+	}
+#endif
+	if (phal->sdio_hisr & SDIO_HISR_CPWM1)
+	{
+		struct reportpwrstate_parm report;
+
+#ifdef CONFIG_LPS_RPWM_TIMER
+		u8 bcancelled;
+		_cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);
+#endif // CONFIG_LPS_RPWM_TIMER
+
+		report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8703B);
+
+#ifdef CONFIG_LPS_LCLK
+		//cpwm_int_hdl(padapter, &report);
+		_set_workitem(&(pwrctl->cpwm_event));
+#endif
+	}
+
+	if (phal->sdio_hisr & SDIO_HISR_TXERR)
+	{
+		u8 *status;
+		u32 addr;
+
+		status = rtw_malloc(4);
+		if (status)
+		{
+			addr = REG_TXDMA_STATUS;
+			HalSdioGetCmdAddr8703BSdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
+			_sd_read(pintfhdl, addr, 4, status);
+			_sd_write(pintfhdl, addr, 4, status);
+			DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status));
+			rtw_mfree(status, 4);
+		} else {
+			DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
+		}
+	}
+
+	if (phal->sdio_hisr & SDIO_HISR_TXBCNOK)
+	{
+		DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
+	}
+
+	if (phal->sdio_hisr & SDIO_HISR_TXBCNERR)
+	{
+		DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
+	}
+#ifndef CONFIG_C2H_PACKET_EN
+	if (phal->sdio_hisr & SDIO_HISR_C2HCMD)
+	{
+		struct c2h_evt_hdr_88xx *c2h_evt;
+
+		DBG_8192C("%s: C2H Command\n", __func__);
+		if ((c2h_evt = (struct c2h_evt_hdr_88xx*)rtw_zmalloc(16)) != NULL) {
+			if (rtw_hal_c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) {
+				if (c2h_id_filter_ccx_8703b((u8 *)c2h_evt)) {
+					/* Handle CCX report here */
+					rtw_hal_c2h_handler(padapter, (u8 *)c2h_evt);
+					rtw_mfree((u8*)c2h_evt, 16);
+				} else {
+					rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt);
+				}
+			}
+		} else {
+			/* Error handling for malloc fail */
+			if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS)
+				DBG_871X("%s rtw_cbuf_push fail\n", __func__);
+			_set_workitem(&padapter->evtpriv.c2h_wk);
+		}
+	}
+#endif	
+
+	if (phal->sdio_hisr & SDIO_HISR_RXFOVW)
+	{
+		DBG_8192C("%s: Rx Overflow\n", __func__);
+	}
+	if (phal->sdio_hisr & SDIO_HISR_RXERR)
+	{
+		DBG_8192C("%s: Rx Error\n", __func__);
+	}
+
+	if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST)
+	{
+		struct recv_buf *precvbuf;
+		int alloc_fail_time=0;
+		u32 hisr;
+
+//		DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize);
+		phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
+		do {
+			phal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN);
+			if (phal->SdioRxFIFOSize != 0)
+			{
+#ifdef CONFIG_MAC_LOOPBACK_DRIVER
+				sd_recv_loopback(padapter, phal->SdioRxFIFOSize);
+#else
+				precvbuf = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize);
+				if (precvbuf)
+				     	sd_rxhandler(padapter, precvbuf);
+				else
+				{
+					alloc_fail_time++;
+					DBG_871X("%s: recv fail!(time=%d)\n", __func__, alloc_fail_time);
+					if (alloc_fail_time >= 10)
+						break;
+				}
+				phal->SdioRxFIFOSize = 0;
+#endif
+			}
+			else
+				break;
+
+			hisr = 0;
+			ReadInterrupt8703BSdio(padapter, &hisr);
+			hisr &= SDIO_HISR_RX_REQUEST;
+			if (!hisr)
+				break;
+		} while (1);
+
+		if (alloc_fail_time == 10)
+			DBG_871X("%s: exit because recv failed more than 10 times!\n", __func__);
+	}
+}
+
+void sd_int_hdl(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE phal;
+
+
+	if (RTW_CANNOT_RUN(padapter))
+		return;
+
+	phal = GET_HAL_DATA(padapter);
+
+	phal->sdio_hisr = 0;
+	ReadInterrupt8703BSdio(padapter, &phal->sdio_hisr);
+
+	if (phal->sdio_hisr & phal->sdio_himr)
+	{
+		u32 v32;
+
+		phal->sdio_hisr &= phal->sdio_himr;
+
+		// clear HISR
+		v32 = phal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
+		if (v32) {
+			SdioLocalCmd52Write4Byte(padapter, SDIO_REG_HISR, v32);
+		}
+
+		sd_int_dpc(padapter);
+	} else {
+		RT_TRACE(_module_hci_ops_c_, _drv_err_,
+				("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
+				__FUNCTION__, phal->sdio_hisr, phal->sdio_himr));
+	}
+}
+
+//
+//	Description:
+//		Query SDIO Local register to query current the number of Free TxPacketBuffer page.
+//
+//	Assumption:
+//		1. Running at PASSIVE_LEVEL
+//		2. RT_TX_SPINLOCK is NOT acquired.
+//
+//	Created by Roger, 2011.01.28.
+//
+u8 HalQueryTxBufferStatus8703BSdio(PADAPTER padapter)
+{
+	PHAL_DATA_TYPE phal;
+	u32 NumOfFreePage;
+	//_irqL irql;
+
+
+	phal = GET_HAL_DATA(padapter);
+
+	NumOfFreePage = SdioLocalCmd53Read4Byte(padapter, SDIO_REG_FREE_TXPG);
+
+	//_enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
+	_rtw_memcpy(phal->SdioTxFIFOFreePage, &NumOfFreePage, 4);
+	RT_TRACE(_module_hci_ops_c_, _drv_notice_,
+			("%s: Free page for HIQ(%#x),MIDQ(%#x),LOWQ(%#x),PUBQ(%#x)\n",
+			__FUNCTION__,
+			phal->SdioTxFIFOFreePage[HI_QUEUE_IDX],
+			phal->SdioTxFIFOFreePage[MID_QUEUE_IDX],
+			phal->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
+			phal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
+	//_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql);
+
+	return _TRUE;
+}
+
+//
+//	Description:
+//		Query SDIO Local register to get the current number of TX OQT Free Space.
+//
+u8 HalQueryTxOQTBufferStatus8703BSdio(PADAPTER padapter)
+{
+	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+	pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_OQT_FREE_PG);
+	return _TRUE;
+}
+
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) 
+u8 RecvOnePkt(PADAPTER padapter, u32 size)
+{
+	struct recv_buf *precvbuf;
+	struct dvobj_priv *psddev;
+	PSDIO_DATA psdio_data;
+	struct sdio_func *func;
+
+	u8 res = _FALSE;
+
+	DBG_871X("+%s: size: %d+\n", __func__, size);
+
+	if (padapter == NULL) {
+		DBG_871X(KERN_ERR "%s: padapter is NULL!\n", __func__);
+		return _FALSE;
+	}
+
+	psddev = adapter_to_dvobj(padapter);
+	psdio_data = &psddev->intf_data;
+	func = psdio_data->func;
+
+	if(size) {
+		sdio_claim_host(func);
+		precvbuf = sd_recv_rxfifo(padapter, size);
+
+		if (precvbuf) {
+			//printk("Completed Recv One Pkt.\n");
+			sd_rxhandler(padapter, precvbuf);
+			res = _TRUE;
+		}else{
+			res = _FALSE;
+		}
+		sdio_release_host(func);
+	}
+	DBG_871X("-%s-\n", __func__);
+	return res;
+}
+#endif //CONFIG_WOWLAN
+
-- 
2.34.1

