8723BU: Update 8723BU wifi driver to version v4.3.16_14189.20150519_BTCOEX2015119...
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bu / hal / hal_com.c
index 9e1dfe53ada587f7df78f241c865d8410d0d4971..5c5b09849beaced80788a2b3bdb01d3db6227556 100755 (executable)
 #include <drv_types.h>
 #include "hal_com_h2c.h"
 
-#include "../hal/OUTSRC/odm_precomp.h"
+#include "hal_data.h"
 
-u8 rtw_hal_data_init(_adapter *padapter)
-{
-       if(is_primary_adapter(padapter))        //if(padapter->isprimary)
-       {
-               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->isprimary)
-       {
-               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;
-               }       
-       }
-}
+//#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];
+       u8 buf[128]={0};
        
-       if(IS_81XXC(ChipVersion)){
-               cnt += sprintf((buf+cnt), "Chip Version Info: %s_", IS_92C_SERIAL(ChipVersion)?"CHIP_8192C":"CHIP_8188C");
-       }
-       else if(IS_92D(ChipVersion)){
-               cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8192D_");
-       }
-       else if(IS_8723_SERIES(ChipVersion)){
-               cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8723A_");
-       }
-       else if(IS_8188E(ChipVersion)){
+       if(IS_8188E(ChipVersion)){
                cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8188E_");
        }
        else if(IS_8812_SERIES(ChipVersion)){
@@ -93,26 +59,70 @@ void dump_chip_info(HAL_VERSION     ChipVersion)
        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_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_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
 
@@ -622,10 +632,10 @@ Hal_MappingOutPipe(
 
 void hal_init_macaddr(_adapter *adapter)
 {
-       rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, adapter->eeprompriv.mac_addr);
+       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->pbuddy_adapter->eeprompriv.mac_addr);
+               rtw_hal_set_hwreg(adapter->pbuddy_adapter, HW_VAR_MAC_ADDR, adapter_mac_addr(adapter->pbuddy_adapter));
 #endif
 }
 
@@ -657,7 +667,7 @@ s32 c2h_evt_read(_adapter *adapter, u8 *buf)
        if (buf == NULL)
                goto exit;
 
-#if defined(CONFIG_RTL8192C) || defined(CONFIG_RTL8192D) || defined(CONFIG_RTL8723A) || defined (CONFIG_RTL8188E)
+#if defined (CONFIG_RTL8188E)
 
        trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
 
@@ -684,7 +694,7 @@ s32 c2h_evt_read(_adapter *adapter, u8 *buf)
 
        /* Read the content */
        for (i = 0; i < c2h_evt->plen; i++)
-               c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + sizeof(*c2h_evt) + 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);
@@ -793,7 +803,7 @@ u8 rtw_get_mgntframe_raid(_adapter *adapter,unsigned char network_type)
 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
 {
        u8      i, rf_type, limit;
-       u32     tx_ra_bitmap;
+       u64     tx_ra_bitmap;
 
        if(psta == NULL)
        {
@@ -820,11 +830,14 @@ void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
 #endif //CONFIG_80211AC_VHT
        {
                //n mode ra_bitmap
-               if(psta->htpriv.ht_option) 
+               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
 
@@ -835,7 +848,8 @@ void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
                }
        }
 #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;
 }
@@ -959,7 +973,7 @@ void hw_var_port_switch(_adapter *adapter)
 
        /* write bcn ctl */
 #ifdef CONFIG_BT_COEXIST
-#if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)
+#if defined(CONFIG_RTL8723B)
        // always enable port0 beacon function for PSTDMA
        bcn_ctrl_1 |= EN_BCN_FUNCTION;
        // always disable port1 beacon function for PSTDMA
@@ -1039,289 +1053,4482 @@ void hw_var_port_switch(_adapter *adapter)
 #endif /* CONFIG_CONCURRENT_MODE */
 }
 
-void SetHwReg(_adapter *adapter, u8 variable, u8 *val)
+void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
 {
-       HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
-       DM_ODM_T *odm = &(hal_data->odmpriv);
+       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);
 
-_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;
+void rtw_hal_set_ap_wow_rsvdpage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+       struct  pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+       struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct  hal_ops *pHalFunc = &padapter->HalFunc;
+       u8      res = 0, count = 0, header = 0;
+       u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
+
+       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);
+
+       if (pHalFunc->fill_h2c_cmd != NULL) {
+               res = pHalFunc->fill_h2c_cmd(padapter,
+                               H2C_BCN_RSVDPAGE,
+                               H2C_BCN_RSVDPAGE_LEN,
+                               rsvdparm);
+       } else {
+               DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
+               res = _FAIL;
+       }
 
-               if (IS_81XXC(*hal_ver) ||IS_92D(*hal_ver) || IS_8723_SERIES(*hal_ver) || IS_8188E(*hal_ver)) {
+       rtw_msleep_os(10);
 
-                       while (brate_cfg > 0x1) {
-                               brate_cfg = (brate_cfg >> 1);
-                               rate_index++;
-                       }
-                       rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
+       _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
+
+       SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(
+                       rsvdparm,
+                       rsvdpageloc->LocProbeRsp + header);
+
+       if (pHalFunc->fill_h2c_cmd != NULL) {
+               res = pHalFunc->fill_h2c_cmd(padapter,
+                               H2C_PROBERSP_RSVDPAGE,
+                               H2C_PROBERSP_RSVDPAGE_LEN,
+                               rsvdparm);
+       } else {
+               DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
+               res = _FAIL;
+       }
+
+       rtw_msleep_os(10);
+}
+
+#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));
+}
+
+static 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_warn_on(1);
+                       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);
        }
-               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;
-
-               reg_scr = rtw_read16(adapter, REG_SECCFG);
-               rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable);
-               #else
-               rtw_write8(adapter, REG_SECCFG, *((u8*)val));
-               #endif
+}
+#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);
        }
-               break;
-       case HW_VAR_SEC_DK_CFG:
+#ifdef CONFIG_PNO_SUPPORT
+       else
        {
-               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);
+               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);
                }
-               else /* Disable default key related setting */
-               {
-                       reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK);
+       }
+#endif //CONFIG_PNO_SUPPORT
+#endif // CONFIG_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(2);
+               }
+               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(2);
                }
 
-               rtw_write8(adapter, REG_SECCFG, reg_scr);
+               if (mstatus & BIT1)
+                       res = _FALSE;
+               else
+                       res = _TRUE;
        }
-               break;
-       case HW_VAR_DM_FLAG:
-               odm->SupportAbility = *((u32*)val);
-               break;
-       case HW_VAR_DM_FUNC_OP:
-               if (*((u8*)val) == _TRUE) {
-                       /* save dm flag */
-                       odm->BK_SupportAbility = odm->SupportAbility;                           
-               } else {
-                       /* restore dm flag */
-                       odm->SupportAbility = odm->BK_SupportAbility;
-               }
-               break;
-       case HW_VAR_DM_FUNC_SET:
-               if(*((u32*)val) == DYNAMIC_ALL_FUNC_ENABLE){
-                       struct dm_priv  *dm = &hal_data->dmpriv;
-                       dm->DMFlag = dm->InitDMFlag;
-                       odm->SupportAbility = dm->InitODMFlag;
-               } else {
-                       odm->SupportAbility |= *((u32 *)val);
+       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);
                }
-               break;
-       case HW_VAR_DM_FUNC_CLR:
-               /*
-               * input is already a mask to clear function
-               * don't invert it again! George,Lucas@20130513
-               */
-               odm->SupportAbility &= *((u32 *)val);
-               break;
-       default:
-               if (0)
-               DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" variable(%d) not defined!\n",
-                       FUNC_ADPT_ARG(adapter), variable);
-               break;
+               if (res & BIT(7))
+                       ret = _TRUE;
+               else
+                       ret = _FALSE;
+               DBG_871X("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
        }
+       return ret;
+}
+#endif
 
-_func_exit_;
+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)));
 }
 
-void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
+static void rtw_hal_disable_tx_report(_adapter* adapter)
 {
-       HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
-       DM_ODM_T *odm = &(hal_data->odmpriv);
+       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));
+}
 
-_func_enter_;
+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));
+}
 
-       switch (variable) {
-       case HW_VAR_BASIC_RATE:
-               *((u16*)val) = hal_data->BasicRateSet;
-               break;
-       case HW_VAR_DM_FLAG:
-               *((u32*)val) = odm->SupportAbility;
-               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;
+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));
+}
+
+static u8 rtw_hal_pause_rx_dma(_adapter* adapter)
+{
+       u8 ret = 0;
+       u8 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
+       }while(trycnt--);
+
+       if(trycnt ==0) {
+               DBG_871X_LEVEL(_drv_always_, "Stop RX DMA failed...... \n");
+               ret = _FAIL;
        }
 
-_func_exit_;
+       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");
 
-u8
-SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
-{      
-       HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
-       DM_ODM_T *odm = &(hal_data->odmpriv);
-       u8 bResult = _SUCCESS;
+       tmp = SDIO_HIMR_CPWM2_MSK;
 
-       switch(variable) {
-       case HW_DEF_FA_CNT_DUMP:                
-               //ODM_COMP_COMMON
-               if(*((u8*)value))
-                       odm->DebugComponents |= (ODM_COMP_DIG |ODM_COMP_FA_CNT);
-               else
-                       odm->DebugComponents &= ~(ODM_COMP_DIG |ODM_COMP_FA_CNT);               
-               break;
-       case HAL_DEF_DBG_RX_INFO_DUMP:
-               {
-                       PFALSE_ALARM_STATISTICS FalseAlmCnt = &(odm->FalseAlmCnt);
-                       pDIG_T  pDM_DigTable = &odm->DM_DigTable;
+       res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
 
-                       DBG_871X("============ Rx Info dump ===================\n");
-                       DBG_871X("bLinked = %d, RSSI_Min = %d(%%), CurrentIGI = 0x%x \n",
-                               odm->bLinked, odm->RSSI_Min, pDM_DigTable->CurIGValue);
-                       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 (!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;
+       }
 
-                       if(odm->bLinked){
-                               DBG_871X("RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n", 
-                                       HDATA_RATE(odm->RxRate), odm->RSSI_A, odm->RSSI_B);     
+       return ret;
+}
+#endif //CONFIG_SDIO_HCI, CONFIG_GSPI_HCI
 
-                               #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
-                               rtw_dump_raw_rssi_info(adapter);
-                               #endif
-                       }
-               }               
-               break;          
-       case HW_DEF_ODM_DBG_FLAG:
-               ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_COMP, *((u8Byte*)value));
-               break;
-       case HW_DEF_ODM_DBG_LEVEL:
-               ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_LEVEL, *((u4Byte*)value));
-               break;
-       case HAL_DEF_DBG_DM_FUNC:
-       {
-               u8 dm_func = *((u8*)value);
-               struct dm_priv *dm = &hal_data->dmpriv;
+#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;
+       }
 
-               if(dm_func == 0){ //disable all dynamic func
-                       odm->SupportAbility = DYNAMIC_FUNC_DISABLE;
-                       DBG_8192C("==> Disable all dynamic function...\n");
-               }
-               else if(dm_func == 1){//disable DIG
-                       odm->SupportAbility  &= (~DYNAMIC_BB_DIG);
-                       DBG_8192C("==> Disable DIG...\n");
-               }
-               else if(dm_func == 2){//disable High power
-                       odm->SupportAbility  &= (~DYNAMIC_BB_DYNAMIC_TXPWR);
-               }
-               else if(dm_func == 3){//disable tx power tracking
-                       odm->SupportAbility  &= (~DYNAMIC_RF_CALIBRATION);
-                       DBG_8192C("==> Disable tx power tracking...\n");
-               }
-               else if(dm_func == 4){//disable BT coexistence
-                       dm->DMFlag &= (~DYNAMIC_FUNC_BT);
-               }
-               else if(dm_func == 5){//disable antenna diversity
-                       odm->SupportAbility  &= (~DYNAMIC_BB_ANT_DIV);
-               }
-               else if(dm_func == 6){//turn on all dynamic func
-                       if(!(odm->SupportAbility  & DYNAMIC_BB_DIG)) {
-                               DIG_T   *pDigTable = &odm->DM_DigTable;
-                               pDigTable->CurIGValue= rtw_read8(adapter, 0xc50);
-                       }
-                       dm->DMFlag |= DYNAMIC_FUNC_BT;
-                       odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
-                       DBG_8192C("==> Turn on all dynamic function...\n");
+       do{
+               cam_id = rtw_camid_search(adapter, addr, index);
+               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 {
+                       read_cam(adapter ,cam_id, 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);
                }
-       }
-               break;
-       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;
-       default:
-               DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
-               bResult = _FAIL;
-               break;
-       }
+               index++;
+       }while(index < 4);
 
-       return bResult;
+       rtw_write8(adapter, REG_SECCFG, 0xcc);
 }
 
-u8
-GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
+static void rtw_hal_update_gtk_offload_info(_adapter* adapter)
 {
-       HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
-       DM_ODM_T *odm = &(hal_data->odmpriv);
-       u8 bResult = _SUCCESS;
+       struct security_priv *psecuritypriv = &adapter->securitypriv;
+       u8 defualt_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;
+       }
 
-       switch(variable) {
-               case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
+       _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(read_phy_cam_is_gtk(adapter, defualt_cam_id) == _TRUE)
                        {
-                               struct mlme_priv *pmlmepriv;
-                               struct sta_priv *pstapriv;
-                               struct sta_info *psta;
+                               read_cam(adapter ,defualt_cam_id, get_key);
+                               algorithm = psecuritypriv->dot11PrivacyAlgrthm;
+                               //in defualt cam entry, cam id = key id
+                               ctrl = BIT(15) | BIT6 |(algorithm << 2) | defualt_cam_id;
+                               write_cam(adapter, cam_id, ctrl, addr, get_key);
+                               cam_id++;
+                               ctrl = 0;
+                               write_cam(adapter, defualt_cam_id, ctrl, null_addr, get_key);
+                       }
 
-                               pmlmepriv = &adapter->mlmepriv;
-                               pstapriv = &adapter->stapriv;
-                               psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
-                               if (psta)
-                               {
-                                       *((int*)value) = psta->rssi_stat.UndecoratedSmoothedPWDB;     
-                               }
+                       if (gtk_keyindex < 4 &&(defualt_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]);
                        }
-                       break;
-               case HW_DEF_ODM_DBG_FLAG:
-                       *((u8Byte*)value) = odm->DebugComponents;
-                       break;
-               case HW_DEF_ODM_DBG_LEVEL:
-                       *((u4Byte*)value) = odm->DebugLevel;
-                       break;
-               case HAL_DEF_DBG_DM_FUNC:
-                       *(( u32*)value) =hal_data->odmpriv.SupportAbility;
-                       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;
-               default:
-                       DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
-                       bResult = _FAIL;
-                       break;
-       }
+                       defualt_cam_id++;
+               }while(defualt_cam_id < 4);
 
-       return bResult;
-}
+               rtw_write8(adapter, REG_SECCFG, 0x0c);
+#ifdef CONFIG_GTK_OL_DBG
+               //if (gtk_keyindex != 5)
+               dump_cam_table(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_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_rsvdpage_loc_cmd(_adapter *adapter,
+               PRSVDPAGE_LOC rsvdpageloc)
+{
+       struct hal_ops *pHalFunc = &adapter->HalFunc;
+       u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
+       u8 ret = _FAIL, header = 0;
+
+       header = rtw_read8(adapter, 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(adapter, H2C_BCN_RSVDPAGE,
+                               H2C_BCN_RSVDPAGE_LEN, rsvdparm);
+
+       if (ret == _FAIL)
+               DBG_871X("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
+
+       _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
+
+       SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
+                       rsvdpageloc->LocProbeRsp + header);
+
+       ret = rtw_hal_fill_h2c_cmd(adapter, H2C_PROBERSP_RSVDPAGE,
+                               H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
+
+       if (ret == _FAIL)
+               DBG_871X("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
+
+       return ret;
+}
+
+static u8 rtw_hal_set_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 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN]={0};
+       u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
+       u8 hw_unicast = 0, gpio_pulse_cnt=0;
+       u8 sdio_wakeup_enable = 1;
+       u8 gpio_high_active = 0; //0: low active, 1: high active
+       u8 magic_pkt = 0;
+       u8 ret = _FAIL;
+
+#ifdef CONFIG_GPIO_WAKEUP
+       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;
+
+       DBG_871X("%s(): enable=%d\n", __func__, enable);
+
+       SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
+       SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, 0);
+       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);
+#ifdef CONFIG_PLATFORM_ARM_RK3188
+       SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, 1);
+       SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, 0x04);
+#else
+       SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, 0);
+       SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
+#endif
+
+       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, 1);
+
+               /*
+                * 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, 1);
+               
+               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);
+
+       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(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
+                       dump_TX_FIFO(padapter, 4, PageSize);
+               }
+#endif
+
+               rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
+               rtw_hal_set_wowlan_ctrl_cmd(padapter, enable);
+       }
+_func_exit_;
+       DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);
+}
+#endif //CONFIG_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
+#ifdef CONFIG_IOCTL_CFG80211
+                       if(_TRUE == pwdinfo->wfd_info->wfd_enable)
+#endif //CONFIG_IOCTL_CFG80211
+                       {
+                       len = build_beacon_wfd_ie( pwdinfo, pframe );
+                       }
+#ifdef CONFIG_IOCTL_CFG80211
+                       else
+                       {       
+                               len = 0;
+                               if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
+                               {
+                                       len = pmlmepriv->wfd_beacon_ie_len;
+                                       _rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);     
+                               }
+                       }               
+#endif //CONFIG_IOCTL_CFG80211
+                       pframe += len;
+                       pktlen += len;
+#endif //CONFIG_WFD
+               }
+#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 //CONFIG_WFD
+#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
+#ifdef CONFIG_IOCTL_CFG80211
+       if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
+#endif //CONFIG_IOCTL_CFG80211
+       {
+               wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
+               pframe += wfdielen;
+               pktlen += wfdielen;
+       }
+#ifdef CONFIG_IOCTL_CFG80211
+       else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
+       {
+               //WFD IE
+               _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
+               pktlen += pmlmepriv->wfd_probe_resp_ie_len;
+               pframe += pmlmepriv->wfd_probe_resp_ie_len;             
+       }
+#endif //CONFIG_IOCTL_CFG80211
+#endif //CONFIG_WFD    
+
+       *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 //CONFIG_WFD
+
+       //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 //CONFIG_WFD
+       
+       *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 //CONFIG_WFD
+       
+       //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 //CONFIG_WFD
+
+       *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 //CONFIG_WFD            
+       
+       //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 //CONFIG_WFD
+
+       *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 (rtw_gw_addr_query(padapter)==0) {
+               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
+#endif //CONFIG_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 CONFIG_WOWLAN   
+       u32     ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0;
+       u32     SSIDLegnth = 0;
+       struct security_priv *psecuritypriv = &adapter->securitypriv; //added by xx
+       u8 currentip[4];
+       u8 cur_dot11txpn[8];
+#ifdef CONFIG_GTK_OL
+       struct sta_priv *pstapriv = &adapter->stapriv;
+       struct security_priv *psecpriv = NULL;
+       struct sta_info * psta;
+       u8 kek[RTW_KEK_LEN];
+       u8 kck[RTW_KCK_LEN];
+#endif //CONFIG_GTK_OL
+#ifdef CONFIG_PNO_SUPPORT 
+       int index;
+       u8 ssid_num;
+#endif //CONFIG_PNO_SUPPORT
+#endif
+#ifdef DBG_CONFIG_ERROR_DETECT
+       struct sreset_priv *psrtpriv;
+#endif // DBG_CONFIG_ERROR_DETECT
+
+#ifdef CONFIG_P2P_WOWLAN
+       u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0, P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
+#endif
+
+       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;
+       }
+       
+       RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
+       DBG_871X("%s PageSize: %d, RsvdPageNUm: %d\n",__func__, PageSize, RsvdPageNum);
+       
+       MaxRsvdPageBufSize = RsvdPageNum*PageSize;
+
+       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, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
+       if (CurtPktPageNum == 1)
+               CurtPktPageNum += 1;
+
+       TotalPageNum += CurtPktPageNum;
+
+       BufIndex += (CurtPktPageNum*PageSize);
+
+       //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);
+
+#ifdef CONFIG_WOWLAN
+       if (pwrctl->wowlan_mode == _TRUE &&
+                       check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
+               //ARP RSP * 1 page
+               rtw_get_current_ip_address(adapter, currentip);
+
+               RsvdPageLoc.LocArpRsp= TotalPageNum;
+
+               rtw_hal_construct_ARPRsp(
+                               adapter,
+                               &ReservedPagePacket[BufIndex],
+                               &ARPLegnth,
+                               currentip);
+
+               rtw_hal_fill_fake_txdesc(adapter,
+                               &ReservedPagePacket[BufIndex-TxDescLen],
+                               ARPLegnth, _FALSE, _FALSE, _TRUE);
+
+               CurtPktPageNum = (u8)PageNum(TxDescLen + ARPLegnth, PageSize);
+
+               TotalPageNum += CurtPktPageNum;
+
+               BufIndex += (CurtPktPageNum*PageSize);
+
+               //3 SEC IV * 1 page
+               rtw_get_sec_iv(adapter, cur_dot11txpn,
+                               get_my_bssid(&pmlmeinfo->network));
+
+               RsvdPageLoc.LocRemoteCtrlInfo = TotalPageNum;
+
+               _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen,
+                               cur_dot11txpn, _AES_IV_LEN_);
+
+               CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, PageSize);
+
+               TotalPageNum += CurtPktPageNum;
+#ifdef CONFIG_GTK_OL
+               BufIndex += (CurtPktPageNum*PageSize);
+
+               //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
+               RsvdPageLoc.LocGTKInfo = TotalPageNum;
+               if(IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)){
+                       psecpriv = &adapter->securitypriv;
+                       _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen,
+                                       &psecpriv->dot11PrivacyAlgrthm, 1);
+                       _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+1,
+                                       &psecpriv->dot118021XGrpPrivacy, 1);
+                       _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+2,
+                                       kck, RTW_KCK_LEN);
+                       _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+2+RTW_KCK_LEN,
+                                       kek, RTW_KEK_LEN);
+                       
+                       CurtPktPageNum = (u8)PageNum(TxDescLen + 2 + RTW_KCK_LEN + RTW_KEK_LEN, PageSize);
+               }
+               else{
+                       _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen,
+                                       kck, RTW_KCK_LEN);
+                       _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+RTW_KCK_LEN,
+                                       kek, RTW_KEK_LEN);
+
+                       CurtPktPageNum = (u8)PageNum(TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN, PageSize);
+               }
+#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");
+               }
+#endif
+
+               //DBG_871X("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n", 
+               //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen],
+               //      (TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN));
+
+               TotalPageNum += CurtPktPageNum;
+
+               BufIndex += (CurtPktPageNum*PageSize);
+
+               //3 GTK Response
+               RsvdPageLoc.LocGTKRsp= TotalPageNum;
+               rtw_hal_construct_GTKRsp(
+                               adapter,
+                               &ReservedPagePacket[BufIndex],
+                               &GTKLegnth);
+
+               rtw_hal_fill_fake_txdesc(adapter,
+                               &ReservedPagePacket[BufIndex-TxDescLen],
+                               GTKLegnth, _FALSE, _FALSE, _TRUE);
+#if 0
+               {
+                       int gj;
+                       printk("123GTK pkt=> \n");
+                       for(gj=0; gj < GTKLegnth+TxDescLen; gj++) {
+                               printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
+                               if ((gj + 1)%16==0)
+                                       printk("\n");
+                       }
+                       printk(" <=end\n");
+               }
+#endif
+
+               //DBG_871X("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n", 
+               //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen],
+               //      (TxDescLen + GTKLegnth));
+
+               CurtPktPageNum = (u8)PageNum(TxDescLen + GTKLegnth, PageSize);
+
+               TotalPageNum += CurtPktPageNum;
+
+               BufIndex += (CurtPktPageNum*PageSize);
+
+               //below page is empty for GTK extension memory
+               //3(11) GTK EXT MEM
+               RsvdPageLoc.LocGTKEXTMEM= TotalPageNum;
+
+               CurtPktPageNum = 2;
+
+               TotalPageNum += CurtPktPageNum;
+               //extension memory for FW
+               TotalPacketLen = BufIndex-TxDescLen + (PageSize*CurtPktPageNum);
+#else //CONFIG_GTK_OL
+               TotalPacketLen = BufIndex + _AES_IV_LEN_;
+#endif //CONFIG_GTK_OL
+       } else if (pwrctl->wowlan_pno_enable == _TRUE) {
+#ifdef CONFIG_PNO_SUPPORT
+               if (pwrctl->pno_in_resume == _FALSE &&
+                               pwrctl->pno_inited == _TRUE) {
+
+                       //Broadcast Probe Request
+                       RsvdPageLoc.LocProbePacket = TotalPageNum;
+
+                       DBG_871X("loc_probe_req: %d\n",
+                                       RsvdPageLoc.LocProbePacket);
+
+                       rtw_hal_construct_ProbeReq(
+                               adapter,
+                               &ReservedPagePacket[BufIndex],
+                               &ProbeReqLength,
+                               NULL);
+
+                       rtw_hal_fill_fake_txdesc(adapter,
+                               &ReservedPagePacket[BufIndex-TxDescLen],
+                               ProbeReqLength, _FALSE, _FALSE, _FALSE);
+
+                       CurtPktPageNum =
+                               (u8)PageNum(TxDescLen + ProbeReqLength, PageSize);
+
+                       TotalPageNum += CurtPktPageNum;
+
+                       BufIndex += (CurtPktPageNum*PageSize);
+
+                       //Hidden SSID Probe Request
+                       ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
+
+                       for (index = 0 ; index < ssid_num ; index++) {
+                               pwrctl->pnlo_info->loc_probe_req[index] =
+                                       TotalPageNum;
+
+                               rtw_hal_construct_ProbeReq(
+                                       adapter,
+                                       &ReservedPagePacket[BufIndex],
+                                       &ProbeReqLength,
+                                       &pwrctl->pno_ssid_list->node[index]);
+
+                               rtw_hal_fill_fake_txdesc(adapter,
+                                       &ReservedPagePacket[BufIndex-TxDescLen],
+                                       ProbeReqLength, _FALSE, _FALSE, _FALSE);
+
+                               CurtPktPageNum =
+                                       (u8)PageNum(TxDescLen + ProbeReqLength, PageSize);
+
+                               TotalPageNum += CurtPktPageNum;
+
+                               BufIndex += (CurtPktPageNum*PageSize);
+                       }
+
+                       //PNO INFO Page
+                       RsvdPageLoc.LocPNOInfo = TotalPageNum;
+                       rtw_hal_construct_PNO_info(adapter,
+                                       &ReservedPagePacket[BufIndex -TxDescLen],
+                                       &PNOLength);
+
+                       CurtPktPageNum = (u8)PageNum_128(PNOLength);
+                       TotalPageNum += CurtPktPageNum;
+                       BufIndex += (CurtPktPageNum*PageSize);
+
+                       //SSID List Page
+                       RsvdPageLoc.LocSSIDInfo = TotalPageNum;
+                       rtw_hal_construct_ssid_list(adapter,
+                                       &ReservedPagePacket[BufIndex-TxDescLen],
+                                       &SSIDLegnth);
+
+                       CurtPktPageNum = (u8)PageNum_128(SSIDLegnth);
+                       TotalPageNum += CurtPktPageNum;
+                       BufIndex += (CurtPktPageNum*PageSize);
+
+                       //Scan Info Page
+                       RsvdPageLoc.LocScanInfo = TotalPageNum;
+                       rtw_hal_construct_scan_info(adapter,
+                                       &ReservedPagePacket[BufIndex-TxDescLen],
+                                       &ScanInfoLength);
+
+                       CurtPktPageNum = (u8)PageNum(ScanInfoLength, PageSize);
+                       TotalPageNum += CurtPktPageNum;
+                       BufIndex += (CurtPktPageNum*PageSize);
+                       TotalPacketLen = BufIndex + ScanInfoLength;
+               } else {
+                       TotalPacketLen = BufIndex + QosNullLength;
+               }
+#endif //CONFIG_PNO_SUPPORT
+       } else {
+               TotalPacketLen = BufIndex + QosNullLength;
+       }
+#else //CONFIG_WOWLAN
+       TotalPacketLen = BufIndex + QosNullLength;
+#endif //CONFIG_WOWLAN
+
+#ifdef CONFIG_P2P_WOWLAN
+       if(_TRUE == pwrctl->wowlan_p2p_mode)
+       {
+
+               // P2P Beacon
+               RsvdPageLoc.LocP2PBeacon= TotalPageNum;
+               rtw_hal_construct_P2PBeacon(
+                       adapter,
+                       &ReservedPagePacket[BufIndex],
+                       &P2PBCNLength);
+               rtw_hal_fill_fake_txdesc(adapter, 
+                       &ReservedPagePacket[BufIndex-TxDescLen], 
+                       P2PBCNLength, _FALSE, _FALSE, _FALSE);
+
+               //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", 
+               //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (P2PBCNLength+TxDescLen));
+
+               CurtPktPageNum = (u8)PageNum(TxDescLen + P2PBCNLength, PageSize);
+
+               TotalPageNum += CurtPktPageNum;
+
+               BufIndex += (CurtPktPageNum*PageSize);
+
+               // P2P Probe rsp
+               RsvdPageLoc.LocP2PProbeRsp = TotalPageNum;
+               rtw_hal_construct_P2PProbeRsp(
+                       adapter,
+                       &ReservedPagePacket[BufIndex],
+                       &P2PProbeRspLength);
+               rtw_hal_fill_fake_txdesc(adapter, 
+                       &ReservedPagePacket[BufIndex-TxDescLen], 
+                       P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
+
+               //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", 
+               //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (P2PProbeRspLength+TxDescLen));
+
+               CurtPktPageNum = (u8)PageNum(TxDescLen + P2PProbeRspLength, PageSize);
+
+               TotalPageNum += CurtPktPageNum;
+
+               BufIndex += (CurtPktPageNum*PageSize);
+
+               //P2P nego rsp
+               RsvdPageLoc.LocNegoRsp = TotalPageNum;
+               rtw_hal_construct_P2PNegoRsp(
+                       adapter,
+                       &ReservedPagePacket[BufIndex],
+                       &P2PNegoRspLength);
+               rtw_hal_fill_fake_txdesc(adapter, 
+                       &ReservedPagePacket[BufIndex-TxDescLen], 
+                       P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
+
+               //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
+               //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (NegoRspLength+TxDescLen));
+
+               CurtPktPageNum = (u8)PageNum(TxDescLen + P2PNegoRspLength, PageSize);
+
+               TotalPageNum += CurtPktPageNum;
+
+               BufIndex += (CurtPktPageNum*PageSize);
+               
+               //P2P invite rsp
+               RsvdPageLoc.LocInviteRsp = TotalPageNum;
+               rtw_hal_construct_P2PInviteRsp(
+                       adapter,
+                       &ReservedPagePacket[BufIndex],
+                       &P2PInviteRspLength);
+               rtw_hal_fill_fake_txdesc(adapter, 
+                       &ReservedPagePacket[BufIndex-TxDescLen], 
+                       P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
+
+               //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
+               //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (InviteRspLength+TxDescLen));
+
+               CurtPktPageNum = (u8)PageNum(TxDescLen + P2PInviteRspLength, PageSize);
+
+               TotalPageNum += CurtPktPageNum;
+
+               BufIndex += (CurtPktPageNum*PageSize);
+       
+               //P2P provision discovery rsp
+               RsvdPageLoc.LocPDRsp = TotalPageNum;
+               rtw_hal_construct_P2PProvisionDisRsp(
+                       adapter,
+                       &ReservedPagePacket[BufIndex],
+                       &P2PPDRspLength);
+               rtw_hal_fill_fake_txdesc(adapter, 
+                       &ReservedPagePacket[BufIndex-TxDescLen], 
+                       P2PPDRspLength, _FALSE, _FALSE, _FALSE);
+
+               //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
+               //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (PDRspLength+TxDescLen));
+
+               CurtPktPageNum = (u8)PageNum(TxDescLen + P2PPDRspLength, PageSize);
+
+               TotalPageNum += CurtPktPageNum;
+
+               BufIndex += (CurtPktPageNum*PageSize);
+
+               TotalPacketLen = BufIndex + P2PPDRspLength;
+       }
+#endif //CONFIG_P2P_WOWLAN
+
+       if(TotalPacketLen > MaxRsvdPageBufSize) {
+               DBG_871X("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
+                               __FUNCTION__, TotalPacketLen,MaxRsvdPageBufSize);
+               goto error;
+       } else {
+               // update attribute
+               pattrib = &pcmdframe->attrib;
+               update_mgntframe_attrib(adapter, pattrib);
+               pattrib->qsel = 0x10;
+               pattrib->pktlen = 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);
+       } 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);
+}
+
+#ifdef CONFIG_AP_WOWLAN
+/*
+*Description: Fill the reserved packets that FW will use to RSVD page.
+*Now we just send 2 types packet to rsvd page. (1)Beacon, (2)ProbeRsp.
+*
+*Input: bDLFinished    
+*
+*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 length.
+*
+*TRUE: At the second time, we should send the first packet (default:beacon)
+*to Hw again and set the length in descriptor to the real beacon length.
+*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_AP_fw_rsvd_page(_adapter *padapter , 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 = &padapter->mlmepriv;
+       struct hal_ops *pHalFunc = &padapter->HalFunc;
+       u32     BeaconLength = 0 , ProbeRspLength = 0;
+       u8      *ReservedPagePacket;
+       u8      TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
+       u8      TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
+       u8      currentip[4];
+       u16     BufIndex, PageSize = 0;
+       u32     TotalPacketLen = 0 , MaxRsvdPageBufSize = 0;
+       RSVDPAGE_LOC    RsvdPageLoc;
+#ifdef DBG_CONFIG_ERROR_DETECT
+       struct sreset_priv *psrtpriv;
+#endif /* DBG_CONFIG_ERROR_DETECT */
+
+       DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d\n",
+       FUNC_ADPT_ARG(padapter), get_iface_type(padapter));
+
+       pHalData = GET_HAL_DATA(padapter);
+#ifdef DBG_CONFIG_ERROR_DETECT
+       psrtpriv = &pHalData->srestpriv;
+#endif
+       pxmitpriv = &padapter->xmitpriv;
+       pmlmeext = &padapter->mlmeextpriv;
+       pmlmeinfo = &pmlmeext->mlmext_info;
+       pwrctl = adapter_to_pwrctl(padapter);
+
+       rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
+       DBG_871X("%s PAGE_SIZE: %d\n", __func__, PageSize);
+       
+       if (pHalFunc->hal_get_tx_buff_rsvd_page_num != NULL) {
+               RsvdPageNum =
+                       pHalFunc->hal_get_tx_buff_rsvd_page_num(padapter, _TRUE);
+               DBG_871X("%s RsvdPageNUm: %d\n", __func__, RsvdPageNum);
+       } else {
+               DBG_871X("[Error]: %s, missing tx_buff_rsvd_page_num func!!\n",
+                               __func__);
+               return;
+       }
+       MaxRsvdPageBufSize = RsvdPageNum*PageSize;
+       DBG_871X("%s: RsvdPageNum:%d, PageSize:%d\n", __func__ , RsvdPageNum , PageSize);
+
+       pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
+       if (pcmdframe == NULL) {
+               DBG_871X("%s: alloc ReservedPagePacket fail!\n", __func__);
+               return;
+       }
+
+       ReservedPagePacket = pcmdframe->buf_addr;
+       _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
+
+       /* (1) beacon*/
+       BufIndex = TxDescOffset;
+       rtw_hal_construct_beacon(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(TxDescLen + BeaconLength, PageSize);
+       /*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);
+
+       /* (4) probe response*/
+       RsvdPageLoc.LocProbeRsp = TotalPageNum;
+       rtw_hal_construct_ProbeRsp(
+               padapter,
+               &ReservedPagePacket[BufIndex],
+               &ProbeRspLength,
+               get_my_bssid(&pmlmeinfo->network),
+               _FALSE);
+       rtw_hal_fill_fake_txdesc(padapter,
+                       &ReservedPagePacket[BufIndex-TxDescLen],
+                       ProbeRspLength, _FALSE, _FALSE, _FALSE);
+
+       DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
+               __func__, &ReservedPagePacket[BufIndex-TxDescLen],
+               (ProbeRspLength+TxDescLen));
+
+       CurtPktPageNum = (u8)PageNum(TxDescLen + BeaconLength, PageSize);
+
+       TotalPageNum += CurtPktPageNum;
+
+       BufIndex += (CurtPktPageNum*PageSize);
+
+       TotalPacketLen = BufIndex + ProbeRspLength;
+
+       if (TotalPacketLen > MaxRsvdPageBufSize) {
+               DBG_871X("%s(): ERROR: The rsvd page size is not enough !!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
+                               __func__ , TotalPacketLen , MaxRsvdPageBufSize);
+               goto error;
+       } else {
+               /* update attribute*/
+               pattrib = &pcmdframe->attrib;
+               update_mgntframe_attrib(padapter, pattrib);
+               pattrib->qsel = QSLT_BEACON;
+               pattrib->pktlen = TotalPacketLen - TxDescOffset;
+               pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
+#ifdef CONFIG_PCI_HCI
+               dump_mgntframe(padapter, pcmdframe);
+#else
+               dump_mgntframe_and_wait(padapter, pcmdframe, 100);
+#endif
+       }
+
+       DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n" , __func__ , TotalPacketLen , TotalPageNum);
+       rtw_hal_set_ap_wow_rsvdpage_cmd(padapter, &RsvdPageLoc);
+       if (0)
+               dump_TX_FIFO(padapter , 8 , 512);
+
+       return;
+error:
+       rtw_free_xmitframe(pxmitpriv, pcmdframe);
+}
+
+#endif /*CONFIG_AP_WOWLAN*/
+
+
+
+void SetHwReg(_adapter *adapter, u8 variable, u8 *val)
+{
+       HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+       DM_ODM_T *odm = &(hal_data->odmpriv);
+
+_func_enter_;
+
+       switch (variable) {
+               case HW_VAR_INITIAL_GAIN:
+                       {                               
+                               u8 rx_gain = *((u8 *)(val));
+                               //printk("rx_gain:%x\n",rx_gain);
+                               if(rx_gain == 0xff){//restore rx gain                                   
+                                       //ODM_Write_DIG(podmpriv,pDigTable->BackupIGValue);
+                                       odm_PauseDIG(odm, ODM_RESUME_DIG,rx_gain);
+                               }
+                               else{
+                                       //pDigTable->BackupIGValue = pDigTable->CurIGValue;
+                                       //ODM_Write_DIG(podmpriv,rx_gain);
+                                       odm_PauseDIG(odm, ODM_PAUSE_DIG,rx_gain);
+                               }
+                       }
+                       break;          
+               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;
+
+                       reg_scr = rtw_read16(adapter, REG_SECCFG);
+                       rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable);
+                       #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_DM_FLAG:
+                       odm->SupportAbility = *((u32*)val);
+                       break;
+               case HW_VAR_DM_FUNC_OP:
+                       if (*((u8*)val) == _TRUE) {
+                               /* save dm flag */
+                               odm->BK_SupportAbility = odm->SupportAbility;                           
+                       } else {
+                               /* restore dm flag */
+                               odm->SupportAbility = odm->BK_SupportAbility;
+                       }
+                       break;
+               case HW_VAR_DM_FUNC_SET:
+                       odm->SupportAbility |= *((u32 *)val);
+                       break;
+               case HW_VAR_DM_FUNC_CLR:
+                       /*
+                       * input is already a mask to clear function
+                       * don't invert it again! George,Lucas@20130513
+                       */
+                       odm->SupportAbility &= *((u32 *)val);
+                       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;
+#ifdef CONFIG_WOWLAN
+       case HW_VAR_WOWLAN:
+       {
+               struct wowlan_ioctl_param *poidparam;
+               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;
+
+               poidparam = (struct wowlan_ioctl_param *)val;
+               switch (poidparam->subcode) {
+                       case WOWLAN_ENABLE:
+                               DBG_871X_LEVEL(_drv_always_, "WOWLAN_ENABLE\n");
+
+#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);
+
+                               rtw_hal_set_wowlan_fw(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));
+                                       media_status_rpt =
+                                               (u16)((psta->mac_id<<8)|RT_MEDIA_CONNECT);
+                                       if (psta != NULL) {
+                                               rtw_hal_set_hwreg(adapter,
+                                                               HW_VAR_H2C_MEDIA_STATUS_RPT,
+                                                               (u8 *)&media_status_rpt);
+                                       }
+                               }
+
+                               rtw_msleep_os(2);
+
+                               if (IS_HARDWARE_TYPE_8188E(adapter))
+                                       rtw_hal_disable_tx_report(adapter);
+
+                               //RX DMA stop
+                               res = rtw_hal_pause_rx_dma(adapter);
+                               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(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_cam_table(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
+                               break;
+                       case WOWLAN_DISABLE:
+                               DBG_871X_LEVEL(_drv_always_, "WOWLAN_DISABLE\n");
+
+                               if (!pwrctl->wowlan_pno_enable) {
+                                       psta = rtw_get_stainfo(&adapter->stapriv,
+                                                               get_bssid(pmlmepriv));
+
+                                       if (psta != NULL) {
+                                               media_status_rpt =
+                                                       (u16)((psta->mac_id<<8)|RT_MEDIA_DISCONNECT);
+                                               rtw_hal_set_hwreg(adapter,
+                                                               HW_VAR_H2C_MEDIA_STATUS_RPT,
+                                                               (u8 *)&media_status_rpt);
+                                       } 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);
+                               }
+
+                               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_set_wowlan_fw(adapter, _FALSE);
+
+#ifdef CONFIG_GPIO_WAKEUP
+                               DBG_871X_LEVEL(_drv_always_, "Set Wake GPIO to high for default.\n");
+                               rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 1);
+                               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)) {
+
+                                       //rtw_hal_download_rsvd_page(adapter, RT_MEDIA_CONNECT);
+
+                                       media_status_rpt = RT_MEDIA_CONNECT;
+                                       rtw_hal_set_hwreg(adapter,
+                                               HW_VAR_H2C_FW_JOINBSSRPT,
+                                               (u8 *)&media_status_rpt);
+
+                                       if (psta != NULL) {
+                                               media_status_rpt =
+                                                       (u16)((psta->mac_id<<8)|RT_MEDIA_CONNECT);
+                                               rtw_hal_set_hwreg(adapter,
+                                                               HW_VAR_H2C_MEDIA_STATUS_RPT,
+                                                               (u8 *)&media_status_rpt);
+                                       }
+                               }
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               break;
+#endif //CONFIG_WOWLAN
+#ifdef CONFIG_AP_WOWLAN
+               case HW_VAR_AP_WOWLAN:
+               {
+                       u8 trycnt = 100;
+                       struct wowlan_ioctl_param *poidparam;
+                       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;
+
+                       poidparam = (struct wowlan_ioctl_param *) val;
+                       switch (poidparam->subcode) {
+                       case WOWLAN_AP_ENABLE:
+                               DBG_871X("%s, WOWLAN_AP_ENABLE\n", __func__);
+                               /* 1. Download WOWLAN FW*/
+                               DBG_871X_LEVEL(_drv_always_, "Re-download WoWlan FW!\n");
+#ifdef DBG_CHECK_FW_PS_STATE
+                               if (rtw_fw_ps_state(adapter) == _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*/
+                               do {
+                                       if (rtw_read8(adapter, REG_HMETFR) == 0x00) {
+                                               DBG_871X_LEVEL(_drv_always_, "Ready to change FW.\n");
+                                               break;
+                                       }
+                                       rtw_msleep_os(10);
+                                       DBG_871X_LEVEL(_drv_always_, "trycnt: %d\n", (100-trycnt));
+                               } while (trycnt--);
+
+                               if (pHalFunc->hal_set_wowlan_fw != NULL)
+                                       pHalFunc->hal_set_wowlan_fw(adapter, _TRUE);
+                               else
+                                       DBG_871X("hal_set_wowlan_fw is null\n");
+
+                               /* 2. RX DMA stop*/
+                               DBG_871X_LEVEL(_drv_always_, "Pause DMA\n");
+                               trycnt = 100;
+                               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");
+                                               /*if (Adapter->intf_stop)
+                                                       Adapter->intf_stop(Adapter);
+                                               */
+                                               break;
+                                       }
+                                       /* If RX_DMA is not idle, receive one pkt from DMA*/
+                                       DBG_871X_LEVEL(_drv_always_ , "RX_DMA_IDLE is not true\n");
+                               } while (trycnt--);
+
+                               if (trycnt == 0)
+                                       DBG_871X_LEVEL(_drv_always_ , "Stop RX DMA failed......\n");
+
+                               /* 5. Set Enable WOWLAN H2C command. */
+                               DBG_871X_LEVEL(_drv_always_, "Set Enable AP WOWLan cmd\n");
+                               if (pHalFunc->hal_set_ap_wowlan_cmd != NULL)
+                                       pHalFunc->hal_set_ap_wowlan_cmd(adapter, 1);
+                               else
+                                       DBG_871X("hal_set_ap_wowlan_cmd is null\n");
+               
+                               /* 6. add some delay for H2C cmd ready*/
+                               rtw_msleep_os(10);
+                               /* 7. enable AP power save*/
+
+                               rtw_write8(adapter, REG_MCUTST_WOWLAN, 0);
+
+                               if (adapter->intf_stop)
+                                       adapter->intf_stop(adapter);
+
+#ifdef CONFIG_USB_HCI 
+                               
+#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*/
+                               break;
+                       case WOWLAN_AP_DISABLE:
+                               DBG_871X("%s, WOWLAN_AP_DISABLE\n", __func__);
+                               /* 1. Read wakeup reason*/
+                               pwrctl->wowlan_wake_reason =
+                                       rtw_read8(adapter, REG_MCUTST_WOWLAN);
+
+                               DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x\n",
+                                               pwrctl->wowlan_wake_reason);
+
+                               /* 2. disable AP power save*/
+                               if (pHalFunc->hal_set_ap_ps_wowlan_cmd != NULL)
+                                       pHalFunc->hal_set_ap_ps_wowlan_cmd(adapter, 0);
+                               else
+                                       DBG_871X("hal_set_ap_ps_wowlan_cmd is null\n");
+                               /* 3.  Set Disable WOWLAN H2C command.*/
+                               DBG_871X_LEVEL(_drv_always_, "Set Disable WOWLan cmd\n");
+                               if (pHalFunc->hal_set_ap_wowlan_cmd != NULL)
+                                       pHalFunc->hal_set_ap_wowlan_cmd(adapter, 0);
+                               else
+                                       DBG_871X("hal_set_ap_wowlan_cmd is null\n");
+                               /* 6. add some delay for H2C cmd ready*/
+                               rtw_msleep_os(2);
+#ifdef DBG_CHECK_FW_PS_STATE
+                               if (rtw_fw_ps_state(adapter) == _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*/
+
+                               DBG_871X_LEVEL(_drv_always_, "Release RXDMA\n");
+
+                               rtw_write32(adapter, REG_RXPKT_NUM,
+                                       (rtw_read32(adapter , REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
+
+                               do {
+                                       if (rtw_read8(adapter, REG_HMETFR) == 0x00) {
+                                               DBG_871X_LEVEL(_drv_always_, "Ready to change FW.\n");
+                                               break;
+                                       }
+                                       rtw_msleep_os(10);
+                                       DBG_871X_LEVEL(_drv_always_, "trycnt: %d\n", (100-trycnt));
+                               } while (trycnt--);
+
+                               if (pHalFunc->hal_set_wowlan_fw != NULL)
+                                       pHalFunc->hal_set_wowlan_fw(adapter, _FALSE);
+                               else
+                                       DBG_871X("hal_set_wowlan_fw is null\n");
+#ifdef CONFIG_GPIO_WAKEUP
+                               DBG_871X_LEVEL(_drv_always_, "Set Wake GPIO to high for default.\n");
+                               rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 1);
+#endif
+
+#ifdef CONFIG_CONCURRENT_MODE
+                               if (rtw_buddy_adapter_up(adapter) == _TRUE &&
+                                       check_buddy_fwstate(adapter, WIFI_AP_STATE) == _TRUE) {
+                                       media_status_rpt = RT_MEDIA_CONNECT;
+                                       rtw_hal_set_hwreg(adapter->pbuddy_adapter , HW_VAR_H2C_FW_JOINBSSRPT , (u8 *)&media_status_rpt);
+                                       issue_beacon(adapter->pbuddy_adapter, 0);
+                               } else {
+                                       media_status_rpt = RT_MEDIA_CONNECT;
+                                       rtw_hal_set_hwreg(adapter , HW_VAR_H2C_FW_JOINBSSRPT , (u8 *)&media_status_rpt);
+                                       issue_beacon(adapter, 0);
+                               }
+#else
+                               media_status_rpt = RT_MEDIA_CONNECT;
+                               rtw_hal_set_hwreg(adapter , HW_VAR_H2C_FW_JOINBSSRPT , (u8 *)&media_status_rpt);
+                               issue_beacon(adapter , 0);
+#endif
+
+                               break;
+                       default:
+                               break;
+                       }
+               }
+                       break;
+#endif /*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);
+       DM_ODM_T *odm = &(hal_data->odmpriv);
+
+_func_enter_;
+
+       switch (variable) {
+       case HW_VAR_BASIC_RATE:
+               *((u16*)val) = hal_data->BasicRateSet;
+               break;
+       case HW_VAR_DM_FLAG:
+               *((u32*)val) = odm->SupportAbility;
+               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);
+       DM_ODM_T *odm = &(hal_data->odmpriv);
+       u8 bResult = _SUCCESS;
+
+       switch(variable) {
+       case HW_DEF_FA_CNT_DUMP:                
+               //ODM_COMP_COMMON
+               if(*((u8*)value))
+                       odm->DebugComponents |= (ODM_COMP_DIG |ODM_COMP_FA_CNT);
+               else
+                       odm->DebugComponents &= ~(ODM_COMP_DIG |ODM_COMP_FA_CNT);               
+               break;
+       case HAL_DEF_DBG_RX_INFO_DUMP:
+               {
+                       PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( odm , PHYDM_FALSEALMCNT);
+                       pDIG_T  pDM_DigTable = &odm->DM_DigTable;
+
+                       DBG_871X("============ Rx Info dump ===================\n");
+                       DBG_871X("bLinked = %d, RSSI_Min = %d(%%), CurrentIGI = 0x%x \n",
+                               odm->bLinked, odm->RSSI_Min, pDM_DigTable->CurIGValue);
+                       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(odm->bLinked){
+                               DBG_871X("RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n", 
+                                       HDATA_RATE(odm->RxRate), odm->RSSI_A, odm->RSSI_B);     
+
+                               #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
+                               rtw_dump_raw_rssi_info(adapter);
+                               #endif
+                       }
+               }               
+               break;          
+       case HW_DEF_ODM_DBG_FLAG:
+               ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_COMP, *((u8Byte*)value));
+               break;
+       case HW_DEF_ODM_DBG_LEVEL:
+               ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_LEVEL, *((u4Byte*)value));
+               break;
+       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;
+}
+
+u8
+GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
+{
+       HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+       DM_ODM_T *odm = &(hal_data->odmpriv);
+       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 HW_DEF_ODM_DBG_FLAG:
+                       *((u8Byte*)value) = odm->DebugComponents;
+                       break;
+               case HW_DEF_ODM_DBG_LEVEL:
+                       *((u4Byte*)value) = odm->DebugLevel;
+                       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;
+               default:
+                       DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
+                       bResult = _FAIL;
+                       break;
+       }
+
+       return bResult;
+}
 
 void GetHalODMVar(     
        PADAPTER                                Adapter,
@@ -1382,6 +5589,10 @@ void SetHalODMVar(
                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:
                        {
@@ -1680,20 +5891,18 @@ void rtw_hal_check_rxfifo_full(_adapter *adapter)
        int save_cnt=_FALSE;
        
        //switch counter to RX fifo
-       if(IS_81XXC(pHalData->VersionID) || IS_92D(pHalData->VersionID) 
-               || IS_8188E(pHalData->VersionID) || IS_8723_SERIES(pHalData->VersionID)
-               || IS_8812_SERIES(pHalData->VersionID) || IS_8821_SERIES(pHalData->VersionID))
+       if( IS_8188E(pHalData->VersionID)
+               || IS_8812_SERIES(pHalData->VersionID) || IS_8821_SERIES(pHalData->VersionID)
+               || IS_8723B_SERIES(pHalData->VersionID) || IS_8192E(pHalData->VersionID))
        {
                rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0);
                save_cnt = _TRUE;
        }
-       else if(IS_8723B_SERIES(pHalData->VersionID) || IS_8192E(pHalData->VersionID))
+       else 
        {
-               //printk("8723b or 8192e , MAC_667 set 0xf0\n");
-               rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0);
-               save_cnt = _TRUE;
+               //todo: other chips 
        }
-       //todo: other chips 
+       
                
        if(save_cnt)
        {
@@ -1730,7 +5939,7 @@ void linked_info_dump(_adapter *padapter,u8 benable)
                #endif // CONFIG_IPS
 
                #ifdef CONFIG_LPS       
-               rtw_pm_set_lps(padapter, pwrctrlpriv->ips_org_mode);
+               rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt );
                #endif // CONFIG_LPS
        }
        padapter->bLinkInfoDump = benable ;     
@@ -1817,10 +6026,9 @@ void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
 }
 #endif
 
-#ifdef CONFIG_EFUSE_CONFIG_FILE
 int check_phy_efuse_tx_power_info_valid(PADAPTER padapter) {
-       EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
-       u8* pContent = pEEPROM->efuse_eeprom_data;
+       PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+       u8* pContent = pHalData->efuse_eeprom_data;
        int index = 0;
        u16 tx_index_offset = 0x0000;
 
@@ -1834,21 +6042,25 @@ int check_phy_efuse_tx_power_info_valid(PADAPTER padapter) {
                case RTL8192E:
                        tx_index_offset = EEPROM_TX_PWR_INX_8192E;
                break;
+               case RTL8821:
+                       tx_index_offset = EEPROM_TX_PWR_INX_8821;
+               break;
                default:
                        tx_index_offset = 0x0010;
                break;
        }
-       for (index = 0 ; index < 12 ; index++) {
+       for (index = 0 ; index < 11 ; index++) {
                if (pContent[tx_index_offset + index] == 0xFF) {
                        return _FALSE;
                } else {
-                       DBG_871X("0x%02x ,", pContent[EEPROM_TX_PWR_INX_88E+index]);
+                       DBG_871X("0x%02x ,", pContent[tx_index_offset+index]);
                }
        }
        DBG_871X("\n");
        return _TRUE;
 }
 
+#ifdef CONFIG_EFUSE_CONFIG_FILE
 int check_phy_efuse_macaddr_info_valid(PADAPTER padapter) {
 
        u8 val = 0;
@@ -1885,6 +6097,21 @@ int check_phy_efuse_macaddr_info_valid(PADAPTER padapter) {
                                DBG_871X("%s: interface is GSPI\n", __func__);
                        }
                break;
+               case RTL8821:
+                       if (padapter->interface_type == RTW_USB) {
+                               addr_offset = EEPROM_MAC_ADDR_8821AU;
+                               DBG_871X("%s: interface is USB\n", __func__);
+                       } else if (padapter->interface_type == RTW_SDIO) {
+                               addr_offset = EEPROM_MAC_ADDR_8821AS;
+                               DBG_871X("%s: interface is SDIO\n", __func__);
+                       } else if (padapter->interface_type == RTW_PCIE) {
+                               addr_offset = EEPROM_MAC_ADDR_8821AE;
+                               DBG_871X("%s: interface is PCIE\n", __func__);
+                       } else if (padapter->interface_type == RTW_GSPI) {
+                               //addr_offset = EEPROM_MAC_ADDR_8723BS;
+                               DBG_871X("%s: interface is GSPI\n", __func__);
+                       }
+               break;
        }
 
        if (addr_offset == 0x0000) {
@@ -1910,8 +6137,8 @@ u32 Hal_readPGDataFromConfigFile(
        mm_segment_t fs;
        u8 temp[3];
        loff_t pos = 0;
-       EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
-       u8      *PROMContent = pEEPROM->efuse_eeprom_data;
+       HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
+       u8      *PROMContent = pHalData->efuse_eeprom_data;
 
        temp[2] = 0; // add end of string '\0'
 
@@ -1934,7 +6161,7 @@ u32 Hal_readPGDataFromConfigFile(
        }
 
        set_fs(fs);
-       pEEPROM->bloadfile_fail_flag = _FALSE;
+       pHalData->bloadfile_fail_flag = _FALSE;
 
 #ifdef CONFIG_DEBUG
        DBG_871X("Efuse configure file:\n");
@@ -1960,11 +6187,11 @@ void Hal_ReadMACAddrFromFile(
        u8 source_addr[18];
        loff_t pos = 0;
        u32     curtime = rtw_get_current_time();
-       EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
+       PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
        u8 *head, *end;
 
        _rtw_memset(source_addr, 0, 18);
-       _rtw_memset(pEEPROM->mac_addr, 0, ETH_ALEN);
+       _rtw_memset(pHalData->EEPROMMACAddr, 0, ETH_ALEN);
 
        fs = get_fs();
        set_fs(KERNEL_DS);
@@ -1981,7 +6208,7 @@ void Hal_ReadMACAddrFromFile(
                if (end && (*end == ':') )
                        *end = '\0';
 
-               pEEPROM->mac_addr[i] = simple_strtoul(head, NULL, 16 );
+               pHalData->EEPROMMACAddr[i] = simple_strtoul(head, NULL, 16 );
 
                if (end) {
                        end++;
@@ -1990,29 +6217,29 @@ void Hal_ReadMACAddrFromFile(
        }
 
        set_fs(fs);
-       pEEPROM->bloadmac_fail_flag = _FALSE;
+       pHalData->bloadmac_fail_flag = _FALSE;
 
-       if (rtw_check_invalid_mac_address(pEEPROM->mac_addr) == _TRUE) {
+       if (rtw_check_invalid_mac_address(pHalData->EEPROMMACAddr) == _TRUE) {
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
-               get_random_bytes(pEEPROM->mac_addr, ETH_ALEN);
-               pEEPROM->mac_addr[0] = 0x00;
-               pEEPROM->mac_addr[1] = 0xe0;
-               pEEPROM->mac_addr[2] = 0x4c;
+               get_random_bytes(pHalData->EEPROMMACAddr, ETH_ALEN);
+               pHalData->EEPROMMACAddr[0] = 0x00;
+               pHalData->EEPROMMACAddr[1] = 0xe0;
+               pHalData->EEPROMMACAddr[2] = 0x4c;
 #else
-               pEEPROM->mac_addr[0] = 0x00;
-               pEEPROM->mac_addr[1] = 0xe0;
-               pEEPROM->mac_addr[2] = 0x4c;
-               pEEPROM->mac_addr[3] = (u8)(curtime & 0xff) ;
-               pEEPROM->mac_addr[4] = (u8)((curtime>>8) & 0xff) ;
-               pEEPROM->mac_addr[5] = (u8)((curtime>>16) & 0xff) ;
+               pHalData->EEPROMMACAddr[0] = 0x00;
+               pHalData->EEPROMMACAddr[1] = 0xe0;
+               pHalData->EEPROMMACAddr[2] = 0x4c;
+               pHalData->EEPROMMACAddr[3] = (u8)(curtime & 0xff) ;
+               pHalData->EEPROMMACAddr[4] = (u8)((curtime>>8) & 0xff) ;
+               pHalData->EEPROMMACAddr[5] = (u8)((curtime>>16) & 0xff) ;
 #endif
                 DBG_871X("MAC Address from wifimac error is invalid, assign random MAC !!!\n");
        }
 
        DBG_871X("%s: Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
-                       __func__, pEEPROM->mac_addr[0], pEEPROM->mac_addr[1],
-                       pEEPROM->mac_addr[2], pEEPROM->mac_addr[3],
-                       pEEPROM->mac_addr[4], pEEPROM->mac_addr[5]);
+                       __func__, pHalData->EEPROMMACAddr[0], pHalData->EEPROMMACAddr[1],
+                       pHalData->EEPROMMACAddr[2], pHalData->EEPROMMACAddr[3],
+                       pHalData->EEPROMMACAddr[4], pHalData->EEPROMMACAddr[5]);
 }
 
 void Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8* mac_addr) {
@@ -2050,6 +6277,21 @@ void Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8* mac_addr) {
                                DBG_871X("%s: interface is GSPI\n", __func__);
                        }
                break;
+               case RTL8821:
+                       if (padapter->interface_type == RTW_USB) {
+                               addr_offset = EEPROM_MAC_ADDR_8821AU;
+                               DBG_871X("%s: interface is USB\n", __func__);
+                       } else if (padapter->interface_type == RTW_SDIO) {
+                               addr_offset = EEPROM_MAC_ADDR_8821AS;
+                               DBG_871X("%s: interface is SDIO\n", __func__);
+                       } else if (padapter->interface_type == RTW_PCIE) {
+                               addr_offset = EEPROM_MAC_ADDR_8821AE;
+                               DBG_871X("%s: interface is PCIE\n", __func__);
+                       } else if (padapter->interface_type == RTW_GSPI){
+                               //addr_offset = EEPROM_MAC_ADDR_8723BS;
+                               DBG_871X("%s: interface is GSPI\n", __func__);
+                       }
+               break;
        }
 
        rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
@@ -2094,66 +6336,40 @@ u32 Array_kfreemap[] = {
 void rtw_bb_rf_gain_offset(_adapter *padapter)
 {
        HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
-       u8              value = padapter->eeprompriv.EEPROMRFGainOffset;
+       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,target=0; 
        //DBG_871X("+%s value: 0x%02x+\n", __func__, value);
-#if defined(CONFIG_RTL8723A)
-       if (value & BIT0) {
-               DBG_871X("Offset RF Gain.\n");
-               DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x\n",padapter->eeprompriv.EEPROMRFGainVal);
-               if(padapter->eeprompriv.EEPROMRFGainVal != 0xff){
-                       res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0xd, 0xffffffff);
-                       DBG_871X("Offset RF Gain. reg 0xd=0x%x\n",res);
-                       res &= 0xfff87fff;
-
-                       res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15;
-                       DBG_871X("Offset RF Gain.        reg 0xd=0x%x\n",res);
-
-                       rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET_CCK, RF_GAIN_OFFSET_MASK, res);
-
-                       res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0xe, 0xffffffff);
-                       DBG_871X("Offset RF Gain. reg 0xe=0x%x\n",res);
-                       res &= 0xfffffff0;
-
-                       res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f);
-                       DBG_871X("Offset RF Gain.        reg 0xe=0x%x\n",res);
-
-                       rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET_OFDM, RF_GAIN_OFFSET_MASK, res);
-               }
-               else
-               {
-                       DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x    != 0xff, didn't run Kfree\n",padapter->eeprompriv.EEPROMRFGainVal);
-               }
-       } else {
-               DBG_871X("Using the default RF gain.\n");
-       }
-#elif defined(CONFIG_RTL8723B)
+#if defined(CONFIG_RTL8723B)
        if (value & BIT4) {
                DBG_871X("Offset RF Gain.\n");
-               DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x\n",padapter->eeprompriv.EEPROMRFGainVal);
+               DBG_871X("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n",pHalData->EEPROMRFGainVal);
+               
+               if(pHalData->EEPROMRFGainVal != 0xff){
 
-               if(padapter->eeprompriv.EEPROMRFGainVal != 0xff){
-                       if (pHalData->ant_path == ODM_RF_PATH_A)
-                               GainValue=(padapter->eeprompriv.EEPROMRFGainVal & 0x0f);
-                       else
-                               GainValue=(padapter->eeprompriv.EEPROMRFGainVal & 0xf0)>>4;
+                       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 ) {
+                                if ( v1 == GainValue ) {
                                                DBG_871X("Offset RF Gain. got v1 =0x%x ,v2 =0x%x \n",v1,v2);
                                                target=v2;
                                                break;
                                 }
                        }        
-                       DBG_871X("padapter->eeprompriv.EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n",padapter->eeprompriv.EEPROMRFGainVal,target);
+                       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);
@@ -2162,9 +6378,9 @@ void rtw_bb_rf_gain_offset(_adapter *padapter)
 
                        DBG_871X("Offset RF Gain. After reg 0x7f=0x%08x\n",res);
                        
-               } else {
+               }else {
 
-                       DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x    != 0xff, didn't run Kfree\n",padapter->eeprompriv.EEPROMRFGainVal);
+                       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");
@@ -2174,16 +6390,16 @@ void rtw_bb_rf_gain_offset(_adapter *padapter)
        if (value & BIT4) {
                DBG_871X("8188ES Offset RF Gain.\n");
                DBG_871X("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
-                               padapter->eeprompriv.EEPROMRFGainVal);
+                               pHalData->EEPROMRFGainVal);
 
-               if (padapter->eeprompriv.EEPROMRFGainVal != 0xff) {
+               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 |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f) << 15;
+                       res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
                        DBG_871X("Offset RF Gain. res=0x%x\n",res);
 
                        rtw_hal_write_rfreg(padapter, RF_PATH_A,
@@ -2191,7 +6407,7 @@ void rtw_bb_rf_gain_offset(_adapter *padapter)
                                        RF_GAIN_OFFSET_MASK, res);
                } else {
                        DBG_871X("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
-                                       padapter->eeprompriv.EEPROMRFGainVal);
+                                       pHalData->EEPROMRFGainVal);
                }
        } else {
                DBG_871X("Using the default RF gain.\n");
@@ -2211,12 +6427,53 @@ void rtw_bb_rf_gain_offset(_adapter *padapter)
 }
 #endif //CONFIG_RF_GAIN_OFFSET
 
+#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
+       {
+               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));
+               }
+                                       
+       }
+       else if(cur_wireless_mode >= WIRELESS_11_24N
+                       && cur_wireless_mode <= WIRELESS_MODE_MAX)//N AC mode
+       {
+               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));
+               }
+
+       }
+       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))
        {
@@ -2224,13 +6481,606 @@ void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
                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);
+                               rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
                        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)
+{
+       //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_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
+               //disable dynamic functions, such as high power, DIG
+               Save_DM_Func_Flag(padapter);
+               Switch_DM_Func(padapter, ~(ODM_BB_DIG|ODM_BB_FA_CNT), _FALSE);
+       }
+       else if((padapter->dump_rx_cnt_mode& DUMP_PHY_RX_COUNTER) &&(!(rx_cnt_mode & DUMP_PHY_RX_COUNTER )))
+       {
+               //turn on phy-dynamic functions
+               Restore_DM_Func_Flag(padapter);                 
+               initialgain = 0xff; //restore RX GAIN
+               rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); 
+               
+       }
+}
+       
+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                    
+                       Switch_DM_Func(padapter, (~ODM_BB_DYNAMIC_TXPWR), _FALSE);
+                       break;
+               case HT_IOT_PEER_REALTEK:
+                       //rtw_write16(padapter, 0x4cc, 0xffff);
+                       //rtw_write16(padapter, 0x546, 0x01c0);
+                       //disable high power                    
+                       Switch_DM_Func(padapter, (~ODM_BB_DYNAMIC_TXPWR), _FALSE);
+                       break;
+               default:
+                       pmlmeinfo->turboMode_cts2self = 0;
+                       pmlmeinfo->turboMode_rtsen = 1;
+                       break;  
+       }
+       
 }
 
+
+