net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / os_dep / linux / os_intfs.c
old mode 100755 (executable)
new mode 100644 (file)
index fd7d6a9..b07d7d3
@@ -54,7 +54,7 @@ int rtw_adhoc_tx_pwr = 1;
 int rtw_soft_ap = 0;
 //int smart_ps = 1;
 #ifdef CONFIG_POWER_SAVING
-int rtw_power_mgnt = 1;
+int rtw_power_mgnt = PS_MODE_MAX;
 #ifdef CONFIG_IPS_LEVEL_2
 int rtw_ips_mode = IPS_LEVEL_2;
 #else
@@ -99,17 +99,20 @@ int rtw_uapsd_acbk_en = 0;
 int rtw_uapsd_acbe_en = 0;
 int rtw_uapsd_acvi_en = 0;
 int rtw_uapsd_acvo_en = 0;
-
+#ifdef CONFIG_RTL8814A
+int rtw_pwrtrim_enable = 2; /* disable kfree , rename to power trim disable */
+#else
+int rtw_pwrtrim_enable = 0; /* Default Enalbe  power trim by efuse config */
+#endif
 #ifdef CONFIG_80211N_HT
 int rtw_ht_enable = 1;
 // 0: 20 MHz, 1: 40 MHz, 2: 80 MHz, 3: 160MHz, 4: 80+80MHz
 // 2.4G use bit 0 ~ 3, 5G use bit 4 ~ 7
 // 0x21 means enable 2.4G 40MHz & 5G 80MHz
 int rtw_bw_mode = 0x21;
-int rtw_cbw40_enable = 3; // 0 :diable, bit(0): enable 2.4g, bit(1): enable 5g
-int rtw_ampdu_enable = 1;//for enable tx_ampdu
+int rtw_ampdu_enable = 1;//for enable tx_ampdu ,// 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec)
 int rtw_rx_stbc = 1;// 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ
-int rtw_ampdu_amsdu = 0;// 0: disabled, 1:enabled, 2:auto
+int rtw_ampdu_amsdu = 0;// 0: disabled, 1:enabled, 2:auto . There is an IOT issu with DLINK DIR-629 when the flag turn on
 // Short GI support Bit Map
 // BIT0 - 20MHz, 0: non-support, 1: support
 // BIT1 - 40MHz, 0: non-support, 1: support
@@ -117,11 +120,14 @@ int rtw_ampdu_amsdu = 0;// 0: disabled, 1:enabled, 2:auto
 // BIT3 - 160MHz, 0: non-support, 1: support
 int rtw_short_gi = 0xf;
 // BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx
-int rtw_ldpc_cap = 0x33;
+int rtw_ldpc_cap = 0x00;
 // BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx
 int rtw_stbc_cap = 0x13;
 // BIT0: Enable VHT Beamformer, BIT1: Enable VHT Beamformee, BIT4: Enable HT Beamformer, BIT5: Enable HT Beamformee
 int rtw_beamform_cap = 0x2;
+int rtw_bfer_rf_number = 0; /*BeamformerCapRfNum Rf path number, 0 for auto, others for manual*/
+int rtw_bfee_rf_number = 0; /*BeamformeeCapRfNum  Rf path number, 0 for auto, others for manual*/
+
 #endif //CONFIG_80211N_HT
 
 #ifdef CONFIG_80211AC_VHT
@@ -134,13 +140,32 @@ int rtw_lowrate_two_xmit = 1;//Use 2 path Tx to transmit MCS0~7 and legacy mode
 
 //int rf_config = RF_1T2R;  // 1T2R
 int rtw_rf_config = RF_MAX_TYPE;  //auto
+
 int rtw_low_power = 0;
 #ifdef CONFIG_WIFI_TEST
 int rtw_wifi_spec = 1;//for wifi test
 #else
 int rtw_wifi_spec = 0;
 #endif
-int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX;
+
+int rtw_special_rf_path = 0; //0: 2T2R ,1: only turn on path A 1T1R
+
+char rtw_country_unspecified[] = {0xFF, 0xFF, 0x00};
+char *rtw_country_code = rtw_country_unspecified;
+module_param(rtw_country_code, charp, 0644);
+MODULE_PARM_DESC(rtw_country_code, "The default country code (in alpha2)");
+
+int rtw_channel_plan = RTW_CHPLAN_MAX;
+module_param(rtw_channel_plan, int, 0644);
+MODULE_PARM_DESC(rtw_channel_plan, "The default chplan ID when rtw_alpha2 is not specified or valid");
+
+/*if concurrent softap + p2p(GO) is needed, this param lets p2p response full channel list.
+But Softap must be SHUT DOWN once P2P decide to set up connection and become a GO.*/
+#ifdef CONFIG_FULL_CH_IN_P2P_HANDSHAKE
+int rtw_full_ch_in_p2p_handshake = 1; /* reply full channel list*/
+#else
+int rtw_full_ch_in_p2p_handshake = 0; /* reply only softap channel*/
+#endif
 
 #ifdef CONFIG_BT_COEXIST
 int rtw_btcoex_enable = 1;
@@ -159,6 +184,7 @@ int rtw_AcceptAddbaReq = _TRUE;// 0:Reject AP's Add BA req, 1:Accept AP's Add BA
 int rtw_antdiv_cfg = 2; // 0:OFF , 1:ON, 2:decide by Efuse config
 int rtw_antdiv_type = 0 ; //0:decide by efuse  1: for 88EE, 1Tx and 1RxCG are diversity.(2 Ant with SPDT), 2:  for 88EE, 1Tx and 2Rx are diversity.( 2 Ant, Tx and RxCG are both on aux port, RxCS is on main port ), 3: for 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port)
 
+int rtw_switch_usb3 = _FALSE; /* _FALSE: doesn't switch, _TRUE: switch from usb2.0 to usb 3.0 */
 
 #ifdef CONFIG_USB_AUTOSUSPEND
 int rtw_enusbss = 1;//0:disable,1:enable
@@ -184,10 +210,6 @@ int rtw_hw_wps_pbc = 0;
 int rtw_mc2u_disable = 0;
 #endif // CONFIG_TX_MCAST2UNI
 
-#ifdef CONFIG_DUALMAC_CONCURRENT
-int rtw_dmsp = 0;
-#endif // CONFIG_DUALMAC_CONCURRENT
-
 #ifdef CONFIG_80211D
 int rtw_80211d = 0;
 #endif
@@ -206,11 +228,24 @@ int rtw_qos_opt_enable=0;//0: disable,1:enable
 #endif
 module_param(rtw_qos_opt_enable,int,0644);
 
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM
+int rtw_acs_mode = 1; /*0:disable, 1:enable*/
+module_param(rtw_acs_mode, int, 0644);
+
+int rtw_acs_auto_scan = 0; /*0:disable, 1:enable*/
+module_param(rtw_acs_auto_scan, int, 0644);
+
+#endif
+
 char* ifname = "wlan%d";
 module_param(ifname, charp, 0644);
 MODULE_PARM_DESC(ifname, "The default name to allocate for first interface");
 
-char* if2name = "p2p0";
+#ifdef CONFIG_PLATFORM_ANDROID
+char* if2name = "p2p%d";
+#else //CONFIG_PLATFORM_ANDROID
+char* if2name = "wlan%d";
+#endif //CONFIG_PLATFORM_ANDROID
 module_param(if2name, charp, 0644);
 MODULE_PARM_DESC(if2name, "The default name to allocate for second interface");
 
@@ -221,8 +256,9 @@ int rtw_ext_iface_num  = 1;//primary/secondary iface is excluded
 module_param(rtw_ext_iface_num, int, 0644);
 #endif //CONFIG_MULTI_VIR_IFACES
 
+module_param(rtw_pwrtrim_enable, int, 0644);
 module_param(rtw_initmac, charp, 0644);
-module_param(rtw_channel_plan, int, 0644);
+module_param(rtw_special_rf_path, int, 0644);
 module_param(rtw_chip_version, int, 0644);
 module_param(rtw_rfintfs, int, 0644);
 module_param(rtw_lbkmode, int, 0644);
@@ -244,7 +280,9 @@ module_param(rtw_ampdu_amsdu, int, 0644);
 #ifdef CONFIG_80211AC_VHT
 module_param(rtw_vht_enable, int, 0644);
 #endif //CONFIG_80211AC_VHT
-
+#ifdef CONFIG_BEAMFORMING
+module_param(rtw_beamform_cap, int, 0644);
+#endif
 module_param(rtw_lowrate_two_xmit, int, 0644);
 
 module_param(rtw_rf_config, int, 0644);
@@ -253,9 +291,12 @@ module_param(rtw_smart_ps, int, 0644);
 module_param(rtw_low_power, int, 0644);
 module_param(rtw_wifi_spec, int, 0644);
 
+module_param(rtw_full_ch_in_p2p_handshake, int, 0644);
 module_param(rtw_antdiv_cfg, int, 0644);
 module_param(rtw_antdiv_type, int, 0644);
 
+module_param(rtw_switch_usb3, int, 0644);
+
 module_param(rtw_enusbss, int, 0644);
 module_param(rtw_hwpdn_mode, int, 0644);
 module_param(rtw_hwpwrp_detect, int, 0644);
@@ -278,9 +319,9 @@ MODULE_PARM_DESC(rtw_max_roaming_times,"The max roaming times to try");
 #endif //CONFIG_LAYER2_ROAMING
 
 #ifdef CONFIG_IOL
-int rtw_fw_iol=1;// 0:Disable, 1:enable, 2:by usb speed
+int rtw_fw_iol=1;
 module_param(rtw_fw_iol, int, 0644);
-MODULE_PARM_DESC(rtw_fw_iol,"FW IOL");
+MODULE_PARM_DESC(rtw_fw_iol, "FW IOL. 0:Disable, 1:enable, 2:by usb speed");
 #endif //CONFIG_IOL
 
 #ifdef CONFIG_FILE_FWIMG
@@ -303,10 +344,6 @@ MODULE_PARM_DESC(rtw_fw_mp_bt_file_path, "The path of fw for MP-BT image");
 module_param(rtw_mc2u_disable, int, 0644);
 #endif // CONFIG_TX_MCAST2UNI
 
-#ifdef CONFIG_DUALMAC_CONCURRENT
-module_param(rtw_dmsp, int, 0644);
-#endif // CONFIG_DUALMAC_CONCURRENT
-
 #ifdef CONFIG_80211D
 module_param(rtw_80211d, int, 0644);
 MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism");
@@ -336,6 +373,50 @@ uint rtw_adaptivity_dc_backoff = CONFIG_RTW_ADAPTIVITY_DC_BACKOFF;
 module_param(rtw_adaptivity_dc_backoff, uint, 0644);
 MODULE_PARM_DESC(rtw_adaptivity_dc_backoff, "DC backoff for Adaptivity");
 
+int rtw_adaptivity_th_l2h_ini = CONFIG_RTW_ADAPTIVITY_TH_L2H_INI;
+module_param(rtw_adaptivity_th_l2h_ini, int, 0644);
+MODULE_PARM_DESC(rtw_adaptivity_th_l2h_ini, "TH_L2H_ini for Adaptivity");
+
+int rtw_adaptivity_th_edcca_hl_diff = CONFIG_RTW_ADAPTIVITY_TH_EDCCA_HL_DIFF;
+module_param(rtw_adaptivity_th_edcca_hl_diff, int, 0644);
+MODULE_PARM_DESC(rtw_adaptivity_th_edcca_hl_diff, "TH_EDCCA_HL_diff for Adaptivity");
+
+uint rtw_amplifier_type_2g = CONFIG_RTW_AMPLIFIER_TYPE_2G;
+module_param(rtw_amplifier_type_2g, uint, 0644);
+MODULE_PARM_DESC(rtw_amplifier_type_2g, "BIT3:2G ext-PA, BIT4:2G ext-LNA");
+
+uint rtw_amplifier_type_5g = CONFIG_RTW_AMPLIFIER_TYPE_5G;
+module_param(rtw_amplifier_type_5g, uint, 0644);
+MODULE_PARM_DESC(rtw_amplifier_type_5g, "BIT6:5G ext-PA, BIT7:5G ext-LNA");
+
+uint rtw_RFE_type = CONFIG_RTW_RFE_TYPE;
+module_param(rtw_RFE_type, uint, 0644);
+MODULE_PARM_DESC(rtw_RFE_type, "default init value:64");
+
+uint rtw_GLNA_type = CONFIG_RTW_GLNA_TYPE;
+module_param(rtw_GLNA_type, uint, 0644);
+MODULE_PARM_DESC(rtw_GLNA_type, "default init value:0");
+
+uint rtw_TxBBSwing_2G = 0xFF;
+module_param(rtw_TxBBSwing_2G, uint, 0644);
+MODULE_PARM_DESC(rtw_TxBBSwing_2G, "default init value:0xFF");
+
+uint rtw_TxBBSwing_5G = 0xFF;
+module_param(rtw_TxBBSwing_5G, uint, 0644);
+MODULE_PARM_DESC(rtw_TxBBSwing_5G, "default init value:0xFF");
+
+uint rtw_OffEfuseMask = 0;
+module_param(rtw_OffEfuseMask, uint, 0644);
+MODULE_PARM_DESC(rtw_OffEfuseMask, "default open Efuse Mask value:0");
+
+uint rtw_FileMaskEfuse = 0;
+module_param(rtw_FileMaskEfuse, uint, 0644);
+MODULE_PARM_DESC(rtw_FileMaskEfuse, "default drv Mask Efuse value:0");
+
+uint rtw_pll_ref_clk_sel = CONFIG_RTW_PLL_REF_CLK_SEL;
+module_param(rtw_pll_ref_clk_sel, uint, 0644);
+MODULE_PARM_DESC(rtw_pll_ref_clk_sel, "force pll_ref_clk_sel, 0xF:use autoload value");
+
 #if defined(CONFIG_CALIBRATE_TX_POWER_BY_REGULATORY) //eFuse: Regulatory selection=1
 int rtw_tx_pwr_lmt_enable = 1;
 int rtw_tx_pwr_by_rate = 1;
@@ -343,8 +424,13 @@ int rtw_tx_pwr_by_rate = 1;
 int rtw_tx_pwr_lmt_enable = 0;
 int rtw_tx_pwr_by_rate = 1;
 #else //eFuse: Regulatory selection=2
+#ifdef CONFIG_PCI_HCI
+int rtw_tx_pwr_lmt_enable = 2; // 2- Depend on efuse
+int rtw_tx_pwr_by_rate = 2;// 2- Depend on efuse
+#else // USB & SDIO
 int rtw_tx_pwr_lmt_enable = 0;
 int rtw_tx_pwr_by_rate = 0;
+#endif 
 #endif
 
 module_param(rtw_tx_pwr_lmt_enable, int, 0644);
@@ -353,8 +439,50 @@ MODULE_PARM_DESC(rtw_tx_pwr_lmt_enable,"0:Disable, 1:Enable, 2: Depend on efuse"
 module_param(rtw_tx_pwr_by_rate, int, 0644);
 MODULE_PARM_DESC(rtw_tx_pwr_by_rate,"0:Disable, 1:Enable, 2: Depend on efuse");
 
+static int rtw_target_tx_pwr_2g_a[RATE_SECTION_NUM] = CONFIG_RTW_TARGET_TX_PWR_2G_A;
+static int rtw_target_tx_pwr_2g_a_num = 0;
+module_param_array(rtw_target_tx_pwr_2g_a, int, &rtw_target_tx_pwr_2g_a_num, 0644);
+MODULE_PARM_DESC(rtw_target_tx_pwr_2g_a, "2.4G target tx power (unit:dBm) of RF path A for each rate section, should match the real calibrate power, -1: undefined");
+
+static int rtw_target_tx_pwr_2g_b[RATE_SECTION_NUM] = CONFIG_RTW_TARGET_TX_PWR_2G_B;
+static int rtw_target_tx_pwr_2g_b_num = 0;
+module_param_array(rtw_target_tx_pwr_2g_b, int, &rtw_target_tx_pwr_2g_b_num, 0644);
+MODULE_PARM_DESC(rtw_target_tx_pwr_2g_b, "2.4G target tx power (unit:dBm) of RF path B for each rate section, should match the real calibrate power, -1: undefined");
+
+static int rtw_target_tx_pwr_2g_c[RATE_SECTION_NUM] = CONFIG_RTW_TARGET_TX_PWR_2G_C;
+static int rtw_target_tx_pwr_2g_c_num = 0;
+module_param_array(rtw_target_tx_pwr_2g_c, int, &rtw_target_tx_pwr_2g_c_num, 0644);
+MODULE_PARM_DESC(rtw_target_tx_pwr_2g_c, "2.4G target tx power (unit:dBm) of RF path C for each rate section, should match the real calibrate power, -1: undefined");
+
+static int rtw_target_tx_pwr_2g_d[RATE_SECTION_NUM] = CONFIG_RTW_TARGET_TX_PWR_2G_D;
+static int rtw_target_tx_pwr_2g_d_num = 0;
+module_param_array(rtw_target_tx_pwr_2g_d, int, &rtw_target_tx_pwr_2g_d_num, 0644);
+MODULE_PARM_DESC(rtw_target_tx_pwr_2g_d, "2.4G target tx power (unit:dBm) of RF path D for each rate section, should match the real calibrate power, -1: undefined");
+
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+static int rtw_target_tx_pwr_5g_a[RATE_SECTION_NUM - 1] = CONFIG_RTW_TARGET_TX_PWR_5G_A;
+static int rtw_target_tx_pwr_5g_a_num = 0;
+module_param_array(rtw_target_tx_pwr_5g_a, int, &rtw_target_tx_pwr_5g_a_num, 0644);
+MODULE_PARM_DESC(rtw_target_tx_pwr_5g_a, "5G target tx power (unit:dBm) of RF path A for each rate section, should match the real calibrate power, -1: undefined");
+
+static int rtw_target_tx_pwr_5g_b[RATE_SECTION_NUM - 1] = CONFIG_RTW_TARGET_TX_PWR_5G_B;
+static int rtw_target_tx_pwr_5g_b_num = 0;
+module_param_array(rtw_target_tx_pwr_5g_b, int, &rtw_target_tx_pwr_5g_b_num, 0644);
+MODULE_PARM_DESC(rtw_target_tx_pwr_5g_b, "5G target tx power (unit:dBm) of RF path B for each rate section, should match the real calibrate power, -1: undefined");
+
+static int rtw_target_tx_pwr_5g_c[RATE_SECTION_NUM - 1] = CONFIG_RTW_TARGET_TX_PWR_5G_C;
+static int rtw_target_tx_pwr_5g_c_num = 0;
+module_param_array(rtw_target_tx_pwr_5g_c, int, &rtw_target_tx_pwr_5g_c_num, 0644);
+MODULE_PARM_DESC(rtw_target_tx_pwr_5g_c, "5G target tx power (unit:dBm) of RF path C for each rate section, should match the real calibrate power, -1: undefined");
+
+static int rtw_target_tx_pwr_5g_d[RATE_SECTION_NUM - 1] = CONFIG_RTW_TARGET_TX_PWR_5G_D;
+static int rtw_target_tx_pwr_5g_d_num = 0;
+module_param_array(rtw_target_tx_pwr_5g_d, int, &rtw_target_tx_pwr_5g_d_num, 0644);
+MODULE_PARM_DESC(rtw_target_tx_pwr_5g_d, "5G target tx power (unit:dBm) of RF path D for each rate section, should match the real calibrate power, -1: undefined");
+#endif /* CONFIG_IEEE80211_BAND_5GHZ */
+
 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
-char *rtw_phy_file_path = "";
+char *rtw_phy_file_path = REALTEK_CONFIG_PATH;
 module_param(rtw_phy_file_path, charp, 0644);
 MODULE_PARM_DESC(rtw_phy_file_path, "The path of phy parameter");
 // PHY FILE Bit Map
@@ -373,18 +501,54 @@ module_param(rtw_decrypt_phy_file, int, 0644);
 MODULE_PARM_DESC(rtw_decrypt_phy_file,"Enable Decrypt PHY File");
 #endif
 
-static uint loadparam(PADAPTER padapter, _nic_hdl pnetdev);
 int _netdev_open(struct net_device *pnetdev);
 int netdev_open (struct net_device *pnetdev);
 static int netdev_close (struct net_device *pnetdev);
+#ifdef CONFIG_PLATFORM_INTEL_BYT
+extern int rtw_sdio_set_power(int on);
+#endif //CONFIG_PLATFORM_INTEL_BYT
 
-//#ifdef RTK_DMP_PLATFORM
-uint loadparam( _adapter *padapter,  _nic_hdl  pnetdev)
+void rtw_regsty_load_target_tx_power(struct registry_priv *regsty)
 {
+       int path, rs;
+       int *target_tx_pwr;
+
+       for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
+               if (path == RF_PATH_A)
+                       target_tx_pwr = rtw_target_tx_pwr_2g_a;
+               else if (path == RF_PATH_B)
+                       target_tx_pwr = rtw_target_tx_pwr_2g_b;
+               else if (path == RF_PATH_C)
+                       target_tx_pwr = rtw_target_tx_pwr_2g_c;
+               else if (path == RF_PATH_D)
+                       target_tx_pwr = rtw_target_tx_pwr_2g_d;
+
+               for (rs = CCK; rs < RATE_SECTION_NUM; rs++)
+                       regsty->target_tx_pwr_2g[path][rs] = target_tx_pwr[rs];
+       }
 
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+       for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
+               if (path == RF_PATH_A)
+                       target_tx_pwr = rtw_target_tx_pwr_5g_a;
+               else if (path == RF_PATH_B)
+                       target_tx_pwr = rtw_target_tx_pwr_5g_b;
+               else if (path == RF_PATH_C)
+                       target_tx_pwr = rtw_target_tx_pwr_5g_c;
+               else if (path == RF_PATH_D)
+                       target_tx_pwr = rtw_target_tx_pwr_5g_d;
+
+               for (rs = OFDM; rs < RATE_SECTION_NUM; rs++)
+                       regsty->target_tx_pwr_5g[path][rs - 1] = target_tx_pwr[rs - 1];
+       }
+#endif /* CONFIG_IEEE80211_BAND_5GHZ */
+}
+
+uint loadparam(_adapter *padapter)
+{
        uint status = _SUCCESS;
        struct registry_priv  *registry_par = &padapter->registrypriv;
-       
+
 _func_enter_;
 
        registry_par->chip_version = (u8)rtw_chip_version;
@@ -442,6 +606,8 @@ _func_enter_;
        registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en;
        registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en;
 
+       registry_par->RegPwrTrimEnable = (u8)rtw_pwrtrim_enable;
+       
 #ifdef CONFIG_80211N_HT
        registry_par->ht_enable = (u8)rtw_ht_enable;
        registry_par->bw_mode = (u8)rtw_bw_mode;
@@ -452,6 +618,8 @@ _func_enter_;
        registry_par->ldpc_cap = (u8)rtw_ldpc_cap;
        registry_par->stbc_cap = (u8)rtw_stbc_cap;
        registry_par->beamform_cap = (u8)rtw_beamform_cap;
+       registry_par->beamformer_rf_num = (u8)rtw_bfer_rf_number;
+       registry_par->beamformee_rf_num = (u8)rtw_bfee_rf_number;
 #endif
 
 #ifdef CONFIG_80211AC_VHT
@@ -470,8 +638,20 @@ _func_enter_;
 
        registry_par->wifi_spec = (u8)rtw_wifi_spec;
 
+       if (strlen(rtw_country_code) != 2
+               || is_alpha(rtw_country_code[0]) == _FALSE
+               || is_alpha(rtw_country_code[1]) == _FALSE
+       ) {
+               if (rtw_country_code != rtw_country_unspecified)
+                       DBG_871X_LEVEL(_drv_err_, "%s discard rtw_country_code not in alpha2\n", __func__);
+               _rtw_memset(registry_par->alpha2, 0xFF, 2);
+       } else
+               _rtw_memcpy(registry_par->alpha2, rtw_country_code, 2);
+
        registry_par->channel_plan = (u8)rtw_channel_plan;
+       registry_par->special_rf_path = (u8)rtw_special_rf_path;
 
+       registry_par->full_ch_in_p2p_handshake = (u8)rtw_full_ch_in_p2p_handshake;
 #ifdef CONFIG_BT_COEXIST
        registry_par->btcoex = (u8)rtw_btcoex_enable;
        registry_par->bt_iso = (u8)rtw_bt_iso;
@@ -484,6 +664,8 @@ _func_enter_;
 
        registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg;
        registry_par->antdiv_type = (u8)rtw_antdiv_type;
+       
+       registry_par->switch_usb3 = (u8)rtw_switch_usb3;
 
 #ifdef CONFIG_AUTOSUSPEND
        registry_par->usbss_enable = (u8)rtw_enusbss;//0:disable,1:enable
@@ -511,10 +693,6 @@ _func_enter_;
        registry_par->fw_iol = rtw_fw_iol;
 #endif
 
-#ifdef CONFIG_DUALMAC_CONCURRENT
-       registry_par->dmsp= (u8)rtw_dmsp;
-#endif
-
 #ifdef CONFIG_80211D
        registry_par->enable80211d = (u8)rtw_80211d;
 #endif
@@ -533,15 +711,21 @@ _func_enter_;
        registry_par->ext_iface_num = (u8)rtw_ext_iface_num;
 #endif //CONFIG_MULTI_VIR_IFACES
 
+       registry_par->pll_ref_clk_sel = (u8)rtw_pll_ref_clk_sel;
+
        registry_par->RegEnableTxPowerLimit = (u8)rtw_tx_pwr_lmt_enable;
        registry_par->RegEnableTxPowerByRate = (u8)rtw_tx_pwr_by_rate;
 
+       rtw_regsty_load_target_tx_power(registry_par);
+
        registry_par->RegPowerBase = 14;
-       registry_par->TxBBSwing_2G = 0xFF;
-       registry_par->TxBBSwing_5G = 0xFF;
+       registry_par->TxBBSwing_2G = (s8)rtw_TxBBSwing_2G;
+       registry_par->TxBBSwing_5G = (s8)rtw_TxBBSwing_5G;
        registry_par->bEn_RFE = 1;
-       registry_par->RFE_Type = 64;
-
+       registry_par->RFE_Type = (u8)rtw_RFE_type;
+       registry_par->AmplifierType_2G = (u8)rtw_amplifier_type_2g;
+       registry_par->AmplifierType_5G = (u8)rtw_amplifier_type_5g;
+       registry_par->GLNA_Type = (u8)rtw_GLNA_type;
 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
        registry_par->load_phy_file = (u8)rtw_load_phy_file;
        registry_par->RegDecryptCustomFile = (u8)rtw_decrypt_phy_file;
@@ -554,27 +738,83 @@ _func_enter_;
        registry_par->adaptivity_mode = (u8)rtw_adaptivity_mode;
        registry_par->adaptivity_dml = (u8)rtw_adaptivity_dml;
        registry_par->adaptivity_dc_backoff = (u8)rtw_adaptivity_dc_backoff;
-
+       registry_par->adaptivity_th_l2h_ini = (s8)rtw_adaptivity_th_l2h_ini;
+       registry_par->adaptivity_th_edcca_hl_diff = (s8)rtw_adaptivity_th_edcca_hl_diff;
+
+       registry_par->boffefusemask = (u8)rtw_OffEfuseMask;
+       registry_par->bFileMaskEfuse = (u8)rtw_FileMaskEfuse;
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM
+       registry_par->acs_mode = (u8)rtw_acs_mode;
+       registry_par->acs_auto_scan = (u8)rtw_acs_auto_scan;
+#endif
 _func_exit_;
 
        return status;
 }
 
-static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p)
+/**
+ * rtw_net_set_mac_address
+ * This callback function is used for the Media Access Control address
+ * of each net_device needs to be changed.
+ *
+ * Arguments:
+ * @pnetdev: net_device pointer.
+ * @addr: new MAC address.
+ *
+ * Return:
+ * ret = 0: Permit to change net_device's MAC address.
+ * ret = -1 (Default): Operation not permitted.
+ *
+ * Auther: Arvin Liu
+ * Date: 2015/05/29
+ */
+static int rtw_net_set_mac_address(struct net_device *pnetdev, void *addr)
 {
        _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
-       struct sockaddr *addr = p;
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct sockaddr *sa = (struct sockaddr *)addr;
+       int ret = -1;
 
-       if(padapter->bup == _FALSE)
-       {
-               //DBG_871X("r8711_net_set_mac_address(), MAC=%x:%x:%x:%x:%x:%x\n", addr->sa_data[0], addr->sa_data[1], addr->sa_data[2], addr->sa_data[3],
-               //addr->sa_data[4], addr->sa_data[5]);
-               _rtw_memcpy(padapter->eeprompriv.mac_addr, addr->sa_data, ETH_ALEN);
-               //_rtw_memcpy(pnetdev->dev_addr, addr->sa_data, ETH_ALEN);
-               //padapter->bset_hwaddr = _TRUE;
+       /* only the net_device is in down state to permit modifying mac addr */
+       if ((pnetdev->flags & IFF_UP) == _TRUE) {
+               DBG_871X(FUNC_ADPT_FMT": The net_device's is not in down state\n"
+                       , FUNC_ADPT_ARG(padapter));
+
+               return ret;
        }
 
-       return 0;
+       /* if the net_device is linked, it's not permit to modify mac addr */
+       if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) ||
+               check_fwstate(pmlmepriv, _FW_LINKED) ||
+               check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
+               DBG_871X(FUNC_ADPT_FMT": The net_device's is not idle currently\n"
+                       , FUNC_ADPT_ARG(padapter));
+
+               return ret;
+       }
+
+       /* check whether the input mac address is valid to permit modifying mac addr */
+       if (rtw_check_invalid_mac_address(sa->sa_data, _FALSE) == _TRUE) {
+               DBG_871X(FUNC_ADPT_FMT": Invalid Mac Addr for "MAC_FMT"\n"
+                       , FUNC_ADPT_ARG(padapter), MAC_ARG(sa->sa_data));
+
+               return ret;
+       }
+
+       _rtw_memcpy(adapter_mac_addr(padapter), sa->sa_data, ETH_ALEN); /* set mac addr to adapter */
+       _rtw_memcpy(pnetdev->dev_addr, sa->sa_data, ETH_ALEN); /* set mac addr to net_device */
+
+       rtw_ps_deny(padapter, PS_DENY_IOCTL);
+       LeaveAllPowerSaveModeDirect(padapter); /* leave PS mode for guaranteeing to access hw register successfully */
+       rtw_hal_set_hwreg(padapter, HW_VAR_MAC_ADDR, sa->sa_data); /* set mac addr to mac register */
+       rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
+
+       DBG_871X(FUNC_ADPT_FMT": Set Mac Addr to "MAC_FMT" Successfully\n"
+               , FUNC_ADPT_ARG(padapter), MAC_ARG(sa->sa_data));
+
+       ret = 0;
+
+       return ret;
 }
 
 static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev)
@@ -628,12 +868,14 @@ unsigned int rtw_classify8021d(struct sk_buff *skb)
        return dscp >> 5;
 }
 
 static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
-       , void *accel_priv
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)     
+                               , void *accel_priv
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) 
+                               , select_queue_fallback_t fallback
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
-       , select_queue_fallback_t fallback
+
 #endif
 )
 {
@@ -679,18 +921,29 @@ u16 rtw_recv_select_queue(struct sk_buff *skb)
 }
 
 #endif
-
 static int rtw_ndev_notifier_call(struct notifier_block * nb, unsigned long state, void *ptr)
-{
+{      
 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,11,0))
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 #else
        struct net_device *dev = ptr;
 #endif
 
+       if (dev == NULL)
+               return NOTIFY_DONE;
+
 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
+       if (dev->netdev_ops == NULL)
+               return NOTIFY_DONE;
+
+       if (dev->netdev_ops->ndo_do_ioctl == NULL)
+               return NOTIFY_DONE;
+
        if (dev->netdev_ops->ndo_do_ioctl != rtw_ioctl)
 #else
+       if (dev->do_ioctl == NULL)
+               return NOTIFY_DONE;
+
        if (dev->do_ioctl != rtw_ioctl)
 #endif
                return NOTIFY_DONE;
@@ -725,8 +978,10 @@ int rtw_ndev_init(struct net_device *dev)
 {
        _adapter *adapter = rtw_netdev_priv(dev);
 
-       DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
+       DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" if%d mac_addr="MAC_FMT"\n"
+               , FUNC_ADPT_ARG(adapter), (adapter->iface_id+1), MAC_ARG(dev->dev_addr));
        strncpy(adapter->old_ifname, dev->name, IFNAMSIZ);
+       adapter->old_ifname[IFNAMSIZ-1] = '\0';
        rtw_adapter_proc_init(dev);
 
        return 0;
@@ -736,7 +991,8 @@ void rtw_ndev_uninit(struct net_device *dev)
 {
        _adapter *adapter = rtw_netdev_priv(dev);
 
-       DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
+       DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" if%d\n"
+               , FUNC_ADPT_ARG(adapter), (adapter->iface_id+1));
        rtw_adapter_proc_deinit(dev);
 }
 
@@ -805,6 +1061,22 @@ int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname)
        return 0;
 }
 
+void rtw_hook_if_ops(struct net_device *ndev)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
+       ndev->netdev_ops = &rtw_netdev_ops;
+#else
+       ndev->init = rtw_ndev_init;
+       ndev->uninit = rtw_ndev_uninit;
+       ndev->open = netdev_open;
+       ndev->stop = netdev_close;
+       ndev->hard_start_xmit = rtw_xmit_entry;
+       ndev->set_mac_address = rtw_net_set_mac_address;
+       ndev->get_stats = rtw_net_get_stats;
+       ndev->do_ioctl = rtw_ioctl;
+#endif
+}
+
 struct net_device *rtw_init_netdev(_adapter *old_padapter)
 {
        _adapter *padapter;
@@ -827,28 +1099,15 @@ struct net_device *rtw_init_netdev(_adapter *old_padapter)
        SET_MODULE_OWNER(pnetdev);
 #endif
 
-       //pnetdev->init = NULL;
-
-#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
-       DBG_871X("register rtw_netdev_ops to netdev_ops\n");
-       pnetdev->netdev_ops = &rtw_netdev_ops;
-#else
-       pnetdev->init = rtw_ndev_init;
-       pnetdev->uninit = rtw_ndev_uninit;
-       pnetdev->open = netdev_open;
-       pnetdev->stop = netdev_close;
-       pnetdev->hard_start_xmit = rtw_xmit_entry;
-       pnetdev->set_mac_address = rtw_net_set_mac_address;
-       pnetdev->get_stats = rtw_net_get_stats;
-       pnetdev->do_ioctl = rtw_ioctl;
-#endif
-
+       rtw_hook_if_ops(pnetdev);
 
 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
        pnetdev->features |= NETIF_F_IP_CSUM;
 #endif
+
        //pnetdev->tx_timeout = NULL;
        pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */
+
 #ifdef CONFIG_WIRELESS_EXT
        pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def;
 #endif
@@ -858,58 +1117,245 @@ struct net_device *rtw_init_netdev(_adapter *old_padapter)
        //pnetdev->wireless_data = &priv->wireless_data;
 #endif
 
-       //step 2.
-       loadparam(padapter, pnetdev);
-
        return pnetdev;
+}
+
+int rtw_os_ndev_alloc(_adapter *adapter)
+{
+       int ret = _FAIL;
+       struct net_device *ndev = NULL;
+
+       ndev = rtw_init_netdev(adapter);
+       if (ndev == NULL) {
+               rtw_warn_on(1);
+               goto exit;
+       }
+       #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
+       SET_NETDEV_DEV(ndev, dvobj_to_dev(adapter_to_dvobj(adapter)));
+       #endif
+
+       #ifdef CONFIG_PCI_HCI
+       if (adapter_to_dvobj(adapter)->bdma64)
+               ndev->features |= NETIF_F_HIGHDMA;
+       ndev->irq = adapter_to_dvobj(adapter)->irq;
+       #endif
+
+#if defined(CONFIG_IOCTL_CFG80211)
+       if (rtw_cfg80211_ndev_res_alloc(adapter) != _SUCCESS) {
+               rtw_warn_on(1);
+               goto free_ndev;
+       }
+#endif
+
+       ret = _SUCCESS;
+
+free_ndev:
+       if (ret != _SUCCESS && ndev)
+               rtw_free_netdev(ndev);
+exit:
+       return ret;
+}
+
+void rtw_os_ndev_free(_adapter *adapter)
+{
+#if defined(CONFIG_IOCTL_CFG80211)
+       rtw_cfg80211_ndev_res_free(adapter);
+#endif
 
+       if (adapter->pnetdev) {
+               rtw_free_netdev(adapter->pnetdev);
+               adapter->pnetdev = NULL;
+       }
 }
 
-void rtw_unregister_netdevs(struct dvobj_priv *dvobj)
+int rtw_os_ndev_register(_adapter *adapter, char *name)
 {
-       int i;
-       _adapter *padapter = NULL;
+       int ret = _SUCCESS;
+       struct net_device *ndev = adapter->pnetdev;
 
-       for(i=0;i<dvobj->iface_nums;i++)
-       {
-               struct net_device *pnetdev = NULL;
-               
-               padapter = dvobj->padapters[i];
+#if defined(CONFIG_IOCTL_CFG80211)
+       if (rtw_cfg80211_ndev_res_register(adapter) != _SUCCESS) {
+               rtw_warn_on(1);
+               ret = _FAIL;
+               goto exit;
+       }
+#endif
+
+       /* alloc netdev name */
+       rtw_init_netdev_name(ndev, name);
+
+       _rtw_memcpy(ndev->dev_addr, adapter_mac_addr(adapter), ETH_ALEN);
+
+       /* Tell the network stack we exist */
+       if (register_netdev(ndev) != 0) {
+               DBG_871X(FUNC_NDEV_FMT" if%d Failed!\n", FUNC_NDEV_ARG(ndev), (adapter->iface_id+1));
+               ret = _FAIL;
+       }
+
+#if defined(CONFIG_IOCTL_CFG80211)
+       if (ret != _SUCCESS) {
+               rtw_cfg80211_ndev_res_unregister(adapter);
+               #if !defined(RTW_SINGLE_WIPHY)
+               rtw_wiphy_unregister(adapter_to_wiphy(adapter));
+               #endif
+       }
+#endif
+
+exit:
+       return ret;
+}
+
+void rtw_os_ndev_unregister(_adapter *adapter)
+{
+       struct net_device *netdev = NULL;
+
+       if (adapter == NULL)
+               return;
+
+       adapter->ndev_unregistering = 1;
+
+       netdev = adapter->pnetdev;
+
+#if defined(CONFIG_IOCTL_CFG80211)
+       rtw_cfg80211_ndev_res_unregister(adapter);
+#endif
+
+       if ((adapter->DriverState != DRIVER_DISAPPEAR) && netdev)
+               unregister_netdev(netdev); /* will call netdev_close() */
+
+#if defined(CONFIG_IOCTL_CFG80211) && !defined(RTW_SINGLE_WIPHY)
+       rtw_wiphy_unregister(adapter_to_wiphy(adapter));
+#endif
+
+       adapter->ndev_unregistering = 0;
+}
+
+/**
+ * rtw_os_ndev_init - Allocate and register OS layer net device and relating structures for @adapter
+ * @adapter: the adapter on which this function applies
+ * @name: the requesting net device name
+ *
+ * Returns:
+ * _SUCCESS or _FAIL
+ */
+int rtw_os_ndev_init(_adapter *adapter, char *name)
+{
+       int ret = _FAIL;
+
+       if (rtw_os_ndev_alloc(adapter) != _SUCCESS)
+               goto exit;
+
+       if (rtw_os_ndev_register(adapter, name) != _SUCCESS)
+               goto os_ndev_free;
+
+       ret = _SUCCESS;
+
+os_ndev_free:
+       if (ret != _SUCCESS)
+               rtw_os_ndev_free(adapter);
+exit:
+       return ret;
+}
+
+/**
+ * rtw_os_ndev_deinit - Unregister and free OS layer net device and relating structures for @adapter
+ * @adapter: the adapter on which this function applies
+ */
+void rtw_os_ndev_deinit(_adapter *adapter)
+{
+       rtw_os_ndev_unregister(adapter);
+       rtw_os_ndev_free(adapter);
+}
+
+int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj)
+{
+       int i, status = _SUCCESS;
+       _adapter *adapter;
+
+#if defined(CONFIG_IOCTL_CFG80211)
+       if (rtw_cfg80211_dev_res_alloc(dvobj) != _SUCCESS) {
+               rtw_warn_on(1);
+               status = _FAIL;
+               goto exit;
+       }
+#endif
 
-               if (padapter == NULL)
+       for (i = 0; i < dvobj->iface_nums; i++) {
+
+               if (i >= IFACE_ID_MAX) {
+                       DBG_871X_LEVEL(_drv_err_, "%s %d >= IFACE_ID_MAX\n", __func__, i);
+                       rtw_warn_on(1);
                        continue;
+               }
 
-               pnetdev = padapter->pnetdev;
+               adapter = dvobj->padapters[i];
+               if (adapter && !adapter->pnetdev) {
+                       status = rtw_os_ndev_alloc(adapter);
+                       if (status != _SUCCESS) {
+                               rtw_warn_on(1);
+                               break;
+                       }
+               }
+       }
 
-               if((padapter->DriverState != DRIVER_DISAPPEAR) && pnetdev) {
-               
-                       unregister_netdev(pnetdev); //will call netdev_close()
+       if (status != _SUCCESS) {
+               for (; i >= 0; i--) {
+                       adapter = dvobj->padapters[i];
+                       if (adapter && adapter->pnetdev)
+                               rtw_os_ndev_free(adapter);
                }
+       }
 
-#ifdef CONFIG_IOCTL_CFG80211   
-               rtw_wdev_unregister(padapter->rtw_wdev);
+#if defined(CONFIG_IOCTL_CFG80211)
+       if (status != _SUCCESS)
+               rtw_cfg80211_dev_res_free(dvobj);
 #endif
+exit:
+       return status;
+}
+
+void rtw_os_ndevs_free(struct dvobj_priv *dvobj)
+{
+       int i;
+       _adapter *adapter = NULL;
 
+       for (i = 0; i < dvobj->iface_nums; i++) {
+
+               if (i >= IFACE_ID_MAX) {
+                       DBG_871X_LEVEL(_drv_err_, "%s %d >= IFACE_ID_MAX\n", __func__, i);
+                       rtw_warn_on(1);
+                       continue;
+               }
+
+               adapter = dvobj->padapters[i];
+
+               if (adapter == NULL)
+                       continue;
+
+               rtw_os_ndev_free(adapter);
        }
-       
-}      
+
+#if defined(CONFIG_IOCTL_CFG80211)
+       rtw_cfg80211_dev_res_free(dvobj);
+#endif
+}
 
 u32 rtw_start_drv_threads(_adapter *padapter)
 {
        u32 _status = _SUCCESS;
 
        RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_start_drv_threads\n"));
+
 #ifdef CONFIG_XMIT_THREAD_MODE
-#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_CONCURRENT_MODE)
-       if(padapter->adapter_type == PRIMARY_ADAPTER){
-#endif
-       padapter->xmitThread = kthread_run(rtw_xmit_thread, padapter, "RTW_XMIT_THREAD");
-       if(IS_ERR(padapter->xmitThread))
-               _status = _FAIL;
-#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_CONCURRENT_MODE)
+#if defined(CONFIG_SDIO_HCI)
+       if (is_primary_adapter(padapter))
+#endif         
+       {
+               padapter->xmitThread = kthread_run(rtw_xmit_thread, padapter, "RTW_XMIT_THREAD");
+               if(IS_ERR(padapter->xmitThread))
+                       _status = _FAIL;
        }
-#endif         // CONFIG_SDIO_HCI+CONFIG_CONCURRENT_MODE
-#endif
+#endif //#ifdef CONFIG_XMIT_THREAD_MODE
 
 #ifdef CONFIG_RECV_THREAD_MODE
        padapter->recvThread = kthread_run(rtw_recv_thread, padapter, "RTW_RECV_THREAD");
@@ -917,11 +1363,7 @@ u32 rtw_start_drv_threads(_adapter *padapter)
                _status = _FAIL;
 #endif
 
-
-#ifdef CONFIG_CONCURRENT_MODE
-       if(padapter->isprimary == _TRUE)
-#endif //CONFIG_CONCURRENT_MODE
-       {
+       if (is_primary_adapter(padapter)) {
                padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD");
                if(IS_ERR(padapter->cmdThread))
                        _status = _FAIL;
@@ -945,12 +1387,8 @@ void rtw_stop_drv_threads (_adapter *padapter)
 {
        RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_stop_drv_threads\n"));
 
-#ifdef CONFIG_CONCURRENT_MODE
-       if(padapter->isprimary == _TRUE)
-#endif //CONFIG_CONCURRENT_MODE
-       {
+       if (is_primary_adapter(padapter))
                rtw_stop_cmd_thread(padapter);
-       }
 
 #ifdef CONFIG_EVENT_THREAD_MODE
         _rtw_up_sema(&padapter->evtpriv.evt_notify);
@@ -961,15 +1399,15 @@ void rtw_stop_drv_threads (_adapter *padapter)
 
 #ifdef CONFIG_XMIT_THREAD_MODE
        // Below is to termindate tx_thread...
-#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_CONCURRENT_MODE)
+#if defined(CONFIG_SDIO_HCI) 
        // Only wake-up primary adapter
-       if(padapter->adapter_type == PRIMARY_ADAPTER)
-#endif  //SDIO_HCI + CONCURRENT
+       if (is_primary_adapter(padapter))
+#endif  /*SDIO_HCI */
        {
-       _rtw_up_sema(&padapter->xmitpriv.xmit_sema);
-       _rtw_down_sema(&padapter->xmitpriv.terminate_xmitthread_sema);
+               _rtw_up_sema(&padapter->xmitpriv.xmit_sema);
+               _rtw_down_sema(&padapter->xmitpriv.terminate_xmitthread_sema);
        }
-       RT_TRACE(_module_os_intfs_c_,_drv_info_,("\n drv_halt: rtw_xmit_thread can be terminated ! \n"));
+       RT_TRACE(_module_os_intfs_c_, _drv_info_, ("\n drv_halt: rtw_xmit_thread can be terminated !\n"));
 #endif
 
 #ifdef CONFIG_RECV_THREAD_MODE
@@ -1047,13 +1485,25 @@ u8 rtw_init_default_value(_adapter *padapter)
        RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
        RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
        padapter->bLinkInfoDump = 0;
-       padapter->bNotifyChannelChange = 0;
+       padapter->bNotifyChannelChange = _FALSE;
 #ifdef CONFIG_P2P
        padapter->bShowGetP2PState = 1;
 #endif
 
+       //for debug purpose
        padapter->fix_rate = 0xFF;
-
+       padapter->data_fb = 0;
+       padapter->driver_ampdu_spacing = 0xFF;
+       padapter->driver_rx_ampdu_factor =  0xFF;
+       padapter->driver_rx_ampdu_spacing = 0xFF;
+       padapter->fix_rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
+       padapter->fix_rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
+#ifdef DBG_RX_COUNTER_DUMP
+       padapter->dump_rx_cnt_mode = 0;
+       padapter->drv_rx_cnt_ok = 0;
+       padapter->drv_rx_cnt_crcerror = 0;
+       padapter->drv_rx_cnt_drop = 0;
+#endif 
        return ret;
 }
 
@@ -1070,16 +1520,18 @@ struct dvobj_priv *devobj_init(void)
        _rtw_mutex_init(&pdvobj->h2c_fwcmd_mutex);
        _rtw_mutex_init(&pdvobj->setch_mutex);
        _rtw_mutex_init(&pdvobj->setbw_mutex);
-
-       _rtw_spinlock_init(&pdvobj->lock);
-
-       pdvobj->macid[1] = _TRUE; //macid=1 for bc/mc stainfo
+       _rtw_mutex_init(&pdvobj->rf_read_reg_mutex);
+#ifdef CONFIG_SDIO_INDIRECT_ACCESS
+       _rtw_mutex_init(&pdvobj->sd_indirect_access_mutex);
+#endif
 
        pdvobj->processing_dev_remove = _FALSE;
 
        ATOMIC_SET(&pdvobj->disable_func, 0);
 
+       rtw_macid_ctl_init(&pdvobj->macid_ctl);
        _rtw_spinlock_init(&pdvobj->cam_ctl.lock);
+       _rtw_mutex_init(&pdvobj->cam_ctl.sec_cam_access_mutex);
 
        return pdvobj;
 
@@ -1090,14 +1542,23 @@ void devobj_deinit(struct dvobj_priv *pdvobj)
        if(!pdvobj)
                return;
 
-       _rtw_spinlock_free(&pdvobj->lock);
+       /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
+#if defined(CONFIG_IOCTL_CFG80211)
+       rtw_cfg80211_dev_res_free(pdvobj);
+#endif
 
        _rtw_mutex_free(&pdvobj->hw_init_mutex);
        _rtw_mutex_free(&pdvobj->h2c_fwcmd_mutex);
        _rtw_mutex_free(&pdvobj->setch_mutex);
        _rtw_mutex_free(&pdvobj->setbw_mutex);
+       _rtw_mutex_free(&pdvobj->rf_read_reg_mutex);
+#ifdef CONFIG_SDIO_INDIRECT_ACCESS
+       _rtw_mutex_free(&pdvobj->sd_indirect_access_mutex);
+#endif
 
+       rtw_macid_ctl_deinit(&pdvobj->macid_ctl);
        _rtw_spinlock_free(&pdvobj->cam_ctl.lock);
+       _rtw_mutex_free(&pdvobj->cam_ctl.sec_cam_access_mutex);
 
        rtw_mfree((u8*)pdvobj, sizeof(*pdvobj));
 }      
@@ -1140,7 +1601,7 @@ u8 rtw_reset_drv_sw(_adapter *padapter)
        pwrctrlpriv->pwr_state_check_cnts = 0;
 
        //mlmeextpriv
-       padapter->mlmeextpriv.sitesurvey_res.state= SCAN_DISABLE;
+       mlmeext_set_scan_state(&padapter->mlmeextpriv, SCAN_DISABLE);
 
 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
        rtw_set_signal_stat_timer(&padapter->recvpriv);
@@ -1161,8 +1622,6 @@ _func_enter_;
 
        ret8 = rtw_init_default_value(padapter);
 
-       rtw_init_hal_com_default_value(padapter);
-
        if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL)
        {
                RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init cmd_priv\n"));
@@ -1245,8 +1704,17 @@ _func_enter_;
        }
 
        padapter->stapriv.padapter = padapter;
-       padapter->setband = GHZ24_50;
+       padapter->setband = WIFI_FREQUENCY_BAND_AUTO;
        padapter->fix_rate = 0xFF;
+       padapter->data_fb = 0;
+       padapter->fix_rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
+       padapter->fix_rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
+#ifdef DBG_RX_COUNTER_DUMP
+       padapter->dump_rx_cnt_mode = 0;
+       padapter->drv_rx_cnt_ok = 0;
+       padapter->drv_rx_cnt_crcerror = 0;
+       padapter->drv_rx_cnt_drop = 0;
+#endif 
        rtw_init_bcmc_stainfo(padapter);
 
        rtw_init_pwrctrl_priv(padapter);
@@ -1260,8 +1728,9 @@ _func_enter_;
 #endif
 
        rtw_hal_dm_init(padapter);
+#ifdef CONFIG_SW_LED
        rtw_hal_sw_led_init(padapter);
-
+#endif
 #ifdef DBG_CONFIG_ERROR_DETECT
        rtw_hal_sreset_init(padapter);
 #endif
@@ -1307,16 +1776,22 @@ void rtw_cancel_all_timer(_adapter *padapter)
        RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_cancel_all_timer\n"));
 
        _cancel_timer_ex(&padapter->mlmepriv.assoc_timer);
-       RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel association timer complete! \n"));
+       RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel association timer complete!\n"));
 
-       //_cancel_timer_ex(&padapter->securitypriv.tkip_timer);
-       //RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel tkip_timer! \n"));
+       #if 0
+       _cancel_timer_ex(&padapter->securitypriv.tkip_timer);
+       RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel tkip_timer!\n"));
+       #endif
 
        _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer);
-       RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel scan_to_timer! \n"));
+       RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel scan_to_timer!\n"));
+
+       #ifdef CONFIG_DFS_MASTER
+       _cancel_timer_ex(&padapter->mlmepriv.dfs_master_timer);
+       #endif
 
        _cancel_timer_ex(&padapter->mlmepriv.dynamic_chk_timer);
-       RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel dynamic_chk_timer! \n"));
+       RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel dynamic_chk_timer!\n"));
 
        // cancel sw led timer
        rtw_hal_sw_led_deinit(padapter);
@@ -1349,8 +1824,6 @@ void rtw_cancel_all_timer(_adapter *padapter)
 
 u8 rtw_free_drv_sw(_adapter *padapter)
 {
-       struct net_device *pnetdev = (struct net_device*)padapter->pnetdev;
-
        RT_TRACE(_module_os_intfs_c_,_drv_info_,("==>rtw_free_drv_sw"));
 
 #ifdef CONFIG_WAPI_SUPPORT
@@ -1447,20 +1920,12 @@ int _netdev_vir_if_open(struct net_device *pnetdev)
        if(!primary_padapter)
                goto _netdev_virtual_iface_open_error;
 
-       if(primary_padapter->bup == _FALSE || primary_padapter->hw_init_completed == _FALSE)
-       {
+       if (primary_padapter->bup == _FALSE || !rtw_is_hw_init_completed(primary_padapter))
                _netdev_open(primary_padapter->pnetdev);
-       }
 
        if(padapter->bup == _FALSE && primary_padapter->bup == _TRUE &&
-               primary_padapter->hw_init_completed == _TRUE)
+               rtw_is_hw_init_completed(primary_padapter))
        {
-               int i;
-
-               padapter->bDriverStopped = _FALSE;
-               padapter->bSurpriseRemoved = _FALSE;
-               padapter->bCardDisableWOHSM = _FALSE;
-
                padapter->bFWReady = primary_padapter->bFWReady;
 
                if(rtw_start_drv_threads(padapter) == _FAIL)
@@ -1526,6 +1991,7 @@ static int netdev_vir_if_close(struct net_device *pnetdev)
 
 #ifdef CONFIG_IOCTL_CFG80211
        rtw_scan_abort(padapter);
+       rtw_cfg80211_wait_scan_req_empty(padapter, 200);
        adapter_wdev_data(padapter)->bandroid_scan = _FALSE;
 #endif
 
@@ -1546,12 +2012,21 @@ static const struct net_device_ops rtw_netdev_vir_if_ops = {
 };
 #endif
 
+void rtw_hook_vir_if_ops(struct net_device *ndev)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
+       ndev->netdev_ops = &rtw_netdev_vir_if_ops;
+#else
+       ndev->open = netdev_vir_if_open;
+       ndev->stop = netdev_vir_if_close;
+       ndev->set_mac_address = rtw_net_set_mac_address;
+#endif
+}
+
 _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter,
        void (*set_intf_ops)(_adapter *primary_padapter,struct _io_ops *pops))
 {
-
        int res = _FAIL;
-       struct net_device *pnetdev=NULL;
        _adapter *padapter = NULL;
        struct dvobj_priv *pdvobjpriv;
        u8 mac[ETH_ALEN];
@@ -1559,36 +2034,22 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter,
 /*
        if((primary_padapter->bup == _FALSE) ||
                (rtw_buddy_adapter_up(primary_padapter) == _FALSE))
-       {
-               goto error_rtw_drv_add_iface;
-       }
-
+               goto exit;
 */
-       /****** init netdev ******/
-       pnetdev = rtw_init_netdev(NULL);
-       if (!pnetdev)
-               goto error_rtw_drv_add_iface;
 
-#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
-       DBG_871X("register rtw_netdev_virtual_iface_ops to netdev_ops\n");
-       pnetdev->netdev_ops = &rtw_netdev_vir_if_ops;
-#else
-       pnetdev->open = netdev_vir_if_open;
-       pnetdev->stop = netdev_vir_if_close;
-#endif
+       /****** init adapter ******/
+       padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter));
+       if (padapter == NULL)
+               goto exit;
 
-#ifdef CONFIG_NO_WIRELESS_HANDLERS
-       pnetdev->wireless_handlers = NULL;
-#endif
+       if (loadparam(padapter) != _SUCCESS)
+               goto free_adapter;
 
-       /****** init adapter ******/
-       padapter = rtw_netdev_priv(pnetdev);
        _rtw_memcpy(padapter, primary_padapter, sizeof(_adapter));
 
        //
        padapter->bup = _FALSE;
        padapter->net_closed = _TRUE;
-       padapter->hw_init_completed = _FALSE;
        padapter->dir_dev = NULL;
        padapter->dir_odm = NULL;
 
@@ -1607,92 +2068,52 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter,
        //extended virtual interfaces always are set to port0
        padapter->iface_type = IFACE_PORT0;
 #endif
-       //
-       padapter->pnetdev = pnetdev;
 
-       /****** setup dvobj ******/
+       /****** hook vir if into dvobj ******/
        pdvobjpriv = adapter_to_dvobj(padapter);
        padapter->iface_id = pdvobjpriv->iface_nums;
        pdvobjpriv->padapters[pdvobjpriv->iface_nums++] = padapter;
 
-       SET_NETDEV_DEV(pnetdev, dvobj_to_dev(pdvobjpriv));
-#ifdef CONFIG_IOCTL_CFG80211
-       rtw_wdev_alloc(padapter, dvobj_to_dev(pdvobjpriv));
-#endif //CONFIG_IOCTL_CFG80211
-
-       //set interface_type/chip_type/HardwareType
-       padapter->interface_type = primary_padapter->interface_type;
-       padapter->chip_type = primary_padapter->chip_type;
-       padapter->HardwareType = primary_padapter->HardwareType;
-
-       //step 2. hook HalFunc, allocate HalData
-       //hal_set_hal_ops(padapter);
-       rtw_set_hal_ops(padapter);
-
-       padapter->HalFunc.inirp_init = NULL;
-       padapter->HalFunc.inirp_deinit = NULL;
        padapter->intf_start = NULL;
        padapter->intf_stop = NULL;
 
        //step init_io_priv
        if ((rtw_init_io_priv(padapter, set_intf_ops)) == _FAIL) {
-               RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" \n Can't init io_reqs\n"));
+               RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("\n Can't init io_reqs\n"));
+               goto free_adapter;
        }
 
-       //step read_chip_version
-       rtw_hal_read_chip_version(padapter);
-
-       //step usb endpoint mapping
-       rtw_hal_chip_configure(padapter);
-
-
        //init drv data
        if(rtw_init_drv_sw(padapter)!= _SUCCESS)
-               goto error_rtw_drv_add_iface;
+               goto free_drv_sw;
 
 
        //get mac address from primary_padapter
-       _rtw_memcpy(mac, primary_padapter->eeprompriv.mac_addr, ETH_ALEN);
-
-       if (((mac[0]==0xff) &&(mac[1]==0xff) && (mac[2]==0xff) &&
-            (mac[3]==0xff) && (mac[4]==0xff) &&(mac[5]==0xff)) ||
-           ((mac[0]==0x0) && (mac[1]==0x0) && (mac[2]==0x0) &&
-            (mac[3]==0x0) && (mac[4]==0x0) &&(mac[5]==0x0)))
-       {
-               mac[0] = 0x00;
-               mac[1] = 0xe0;
-               mac[2] = 0x4c;
-               mac[3] = 0x87;
-               mac[4] = 0x11;
-               mac[5] = 0x22;
-       }
-       else
-       {
-               //If the BIT1 is 0, the address is universally administered.
-               //If it is 1, the address is locally administered
-#if 1 //needs enable MBSSID CAM
-               mac[0] |= BIT(1); // locally administered
-               mac[0] |= (padapter->iface_id-1)<<4;
+       _rtw_memcpy(mac, adapter_mac_addr(primary_padapter), ETH_ALEN);
+
+       /*
+       * If the BIT1 is 0, the address is universally administered.
+       * If it is 1, the address is locally administered
+       */
+#if 1 /* needs enable MBSSID CAM */
+       mac[0] |= BIT(1);
+       mac[0] |= (padapter->iface_id-1)<<4;
 #endif
-       }
 
-       _rtw_memcpy(padapter->eeprompriv.mac_addr, mac, ETH_ALEN);
+       _rtw_memcpy(adapter_mac_addr(padapter), mac, ETH_ALEN);
 
        res = _SUCCESS;
 
-       return padapter;
-
-
-error_rtw_drv_add_iface:
-
-       if(padapter)
+free_drv_sw:
+       if (res != _SUCCESS && padapter)
                rtw_free_drv_sw(padapter);
-
-       if (pnetdev)
-               rtw_free_netdev(pnetdev);
-
-       return NULL;
-
+free_adapter:
+       if (res != _SUCCESS && padapter) {
+               rtw_vmfree((u8 *)padapter, sizeof(*padapter));
+               padapter = NULL;
+       }
+exit:
+       return padapter;
 }
 
 void rtw_drv_stop_vir_if(_adapter *padapter)
@@ -1704,12 +2125,9 @@ void rtw_drv_stop_vir_if(_adapter *padapter)
 
        pnetdev = padapter->pnetdev;
 
-       rtw_cancel_all_timer(padapter);
 
        if (padapter->bup == _TRUE)
        {
-               padapter->bDriverStopped = _TRUE;
-
                #ifdef CONFIG_XMIT_ACK
                if (padapter->xmitpriv.ack_tx)
                        rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP);
@@ -1724,26 +2142,24 @@ void rtw_drv_stop_vir_if(_adapter *padapter)
 
                padapter->bup = _FALSE;
        }
+
+       /* cancel timer after thread stop */
+       rtw_cancel_all_timer(padapter);
 }
 
 void rtw_drv_free_vir_if(_adapter *padapter)
 {
-       struct net_device *pnetdev=NULL;
-
        if (padapter == NULL)
                return;
 
        padapter->pbuddy_adapter = NULL;
 
-       pnetdev = padapter->pnetdev;
-
-#ifdef CONFIG_IOCTL_CFG80211
-       rtw_wdev_free(padapter->rtw_wdev);
-#endif //CONFIG_IOCTL_CFG80211
-
        rtw_free_drv_sw(padapter);
 
-       rtw_free_netdev(pnetdev);
+       /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
+       rtw_os_ndev_free(padapter);
+
+       rtw_vmfree((u8 *)padapter, sizeof(_adapter));
 }
 
 void rtw_drv_stop_vir_ifaces(struct dvobj_priv *dvobj)
@@ -1793,20 +2209,35 @@ int _netdev_if2_open(struct net_device *pnetdev)
 
        DBG_871X("+871x_drv - if2_open, bup=%d\n", padapter->bup);
 
-       if(primary_padapter->bup == _FALSE || primary_padapter->hw_init_completed == _FALSE)
+#ifdef CONFIG_PLATFORM_INTEL_BYT
+       if (padapter->bup == _FALSE)
        {
-               _netdev_open(primary_padapter->pnetdev);
+               u8 mac[ETH_ALEN];
+
+               /* get mac address from primary_padapter */
+               if (primary_padapter->bup == _FALSE)
+                       rtw_macaddr_cfg(adapter_mac_addr(primary_padapter), get_hal_mac_addr(primary_padapter));
+
+               _rtw_memcpy(mac, adapter_mac_addr(primary_padapter), ETH_ALEN);
+
+               /*
+               * If the BIT1 is 0, the address is universally administered.
+               * If it is 1, the address is locally administered
+               */
+               mac[0] |= BIT(1);
+
+               _rtw_memcpy(adapter_mac_addr(padapter), mac, ETH_ALEN);
+               rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));
+               _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN);
        }
+#endif //CONFIG_PLATFORM_INTEL_BYT
+
+       if (primary_padapter->bup == _FALSE || !rtw_is_hw_init_completed(primary_padapter))
+               _netdev_open(primary_padapter->pnetdev);
 
        if(padapter->bup == _FALSE && primary_padapter->bup == _TRUE &&
-               primary_padapter->hw_init_completed == _TRUE)
+               rtw_is_hw_init_completed(primary_padapter))
        {
-               int i;
-
-               padapter->bDriverStopped = _FALSE;
-               padapter->bSurpriseRemoved = _FALSE;
-               padapter->bCardDisableWOHSM = _FALSE;
-
                padapter->bFWReady = primary_padapter->bFWReady;
 
                //if (init_mlme_ext_priv(padapter) == _FAIL)
@@ -1858,6 +2289,13 @@ int netdev_if2_open(struct net_device *pnetdev)
 {
        int ret;
        _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
+       struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
+
+       if (pwrctrlpriv->bInSuspend == _TRUE)
+       {
+               DBG_871X("+871x_drv - netdev_if2_open, bInSuspend=%d\n", pwrctrlpriv->bInSuspend);
+               return 0;
+       }
 
        _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL);
        ret = _netdev_if2_open(pnetdev);
@@ -1874,8 +2312,10 @@ int netdev_if2_open(struct net_device *pnetdev)
 static int netdev_if2_close(struct net_device *pnetdev)
 {
        _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
+       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 
        padapter->net_closed = _TRUE;
+       pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
 
        if(pnetdev)
        {
@@ -1883,11 +2323,13 @@ static int netdev_if2_close(struct net_device *pnetdev)
        }
 
 #ifdef CONFIG_P2P
-       rtw_p2p_enable(padapter, P2P_ROLE_DISABLE);
+       if (!rtw_p2p_chk_role(&padapter->wdinfo, P2P_ROLE_DISABLE))
+               rtw_p2p_enable(padapter, P2P_ROLE_DISABLE);
 #endif
 
 #ifdef CONFIG_IOCTL_CFG80211
        rtw_scan_abort(padapter);
+       rtw_cfg80211_wait_scan_req_empty(padapter, 200);
        adapter_wdev_data(padapter)->bandroid_scan = _FALSE;
 #endif
 
@@ -1910,42 +2352,40 @@ static const struct net_device_ops rtw_netdev_if2_ops = {
 };
 #endif
 
+void rtw_hook_if2_ops(struct net_device *ndev)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
+       ndev->netdev_ops = &rtw_netdev_if2_ops;
+#else
+       ndev->init = rtw_ndev_init;
+       ndev->uninit = rtw_ndev_uninit;
+       ndev->open = netdev_if2_open;
+       ndev->stop = netdev_if2_close;
+       ndev->set_mac_address = rtw_net_set_mac_address;
+#endif
+}
+
 _adapter *rtw_drv_if2_init(_adapter *primary_padapter, 
        void (*set_intf_ops)(_adapter *primary_padapter,struct _io_ops *pops))
 {
        int res = _FAIL;
-       struct net_device *pnetdev = NULL;
        _adapter *padapter = NULL;
        struct dvobj_priv *pdvobjpriv;
        u8 mac[ETH_ALEN];
 
-       /****** init netdev ******/
-       pnetdev = rtw_init_netdev(NULL);
-       if (!pnetdev)
-               goto error_rtw_drv_if2_init;
-
-#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
-       DBG_871X("register rtw_netdev_if2_ops to netdev_ops\n");
-       pnetdev->netdev_ops = &rtw_netdev_if2_ops;
-#else
-       pnetdev->init = rtw_ndev_init;
-       pnetdev->uninit = rtw_ndev_uninit;
-       pnetdev->open = netdev_if2_open;
-       pnetdev->stop = netdev_if2_close;
-#endif
+       /****** init adapter ******/
+       padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter));
+       if (padapter == NULL)
+               goto exit;
 
-#ifdef CONFIG_NO_WIRELESS_HANDLERS
-       pnetdev->wireless_handlers = NULL;
-#endif
+       if (loadparam(padapter) != _SUCCESS)
+               goto free_adapter;
 
-       /****** init adapter ******/
-       padapter = rtw_netdev_priv(pnetdev);
-       _rtw_memcpy(padapter, primary_padapter, sizeof(_adapter));
+       _rtw_memcpy(padapter, primary_padapter, sizeof(*padapter));
 
        //
        padapter->bup = _FALSE;
        padapter->net_closed = _TRUE;
-       padapter->hw_init_completed = _FALSE;
        padapter->dir_dev = NULL;
        padapter->dir_odm = NULL;
 
@@ -1959,116 +2399,67 @@ _adapter *rtw_drv_if2_init(_adapter *primary_padapter,
 #else
        padapter->iface_type = IFACE_PORT0;
 #endif  //CONFIG_HWPORT_SWAP
-       //
-       padapter->pnetdev = pnetdev;
 
-       /****** setup dvobj ******/
+       /****** hook if2 into dvobj ******/
        pdvobjpriv = adapter_to_dvobj(padapter);
-       pdvobjpriv->if2 = padapter;
        pdvobjpriv->padapters[pdvobjpriv->iface_nums++] = padapter;
 
-       SET_NETDEV_DEV(pnetdev, dvobj_to_dev(pdvobjpriv));
-       #ifdef CONFIG_IOCTL_CFG80211
-       rtw_wdev_alloc(padapter, dvobj_to_dev(pdvobjpriv));
-       #endif //CONFIG_IOCTL_CFG80211
-
-       //set interface_type/chip_type/HardwareType
-       padapter->interface_type = primary_padapter->interface_type;
-       padapter->chip_type = primary_padapter->chip_type;
-       padapter->HardwareType = primary_padapter->HardwareType;
-
-       //step 2. hook HalFunc, allocate HalData
-       //hal_set_hal_ops(padapter);
-       rtw_set_hal_ops(padapter);
-
-       padapter->HalFunc.inirp_init = NULL;
-       padapter->HalFunc.inirp_deinit = NULL;
-
        //
        padapter->intf_start = primary_padapter->intf_start;
        padapter->intf_stop = primary_padapter->intf_stop;
 
        //step init_io_priv
        if ((rtw_init_io_priv(padapter, set_intf_ops)) == _FAIL) {
-               RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" \n Can't init io_reqs\n"));
+               RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("\n Can't init io_reqs\n"));
+               goto free_adapter;
        }
 
-       //step read_chip_version
-       rtw_hal_read_chip_version(padapter);
-
-       //step usb endpoint mapping
-       rtw_hal_chip_configure(padapter);
-
-
        //init drv data
        if(rtw_init_drv_sw(padapter)!= _SUCCESS)
-               goto error_rtw_drv_if2_init;
+               goto free_drv_sw;
 
 
-       //get mac address from primary_padapter
-       _rtw_memcpy(mac, primary_padapter->eeprompriv.mac_addr, ETH_ALEN);
-
-       if (((mac[0]==0xff) &&(mac[1]==0xff) && (mac[2]==0xff) &&
-            (mac[3]==0xff) && (mac[4]==0xff) &&(mac[5]==0xff)) ||
-           ((mac[0]==0x0) && (mac[1]==0x0) && (mac[2]==0x0) &&
-            (mac[3]==0x0) && (mac[4]==0x0) &&(mac[5]==0x0)))
-       {
-               mac[0] = 0x00;
-               mac[1] = 0xe0;
-               mac[2] = 0x4c;
-               mac[3] = 0x87;
-               mac[4] = 0x11;
-               mac[5] = 0x22;
-       }
-       else
-       {
-               //If the BIT1 is 0, the address is universally administered.
-               //If it is 1, the address is locally administered
-               mac[0] |= BIT(1); // locally administered
+       /* get mac address from primary_padapter */
+       _rtw_memcpy(mac, adapter_mac_addr(primary_padapter), ETH_ALEN);
 
-       }
+       /*
+       * If the BIT1 is 0, the address is universally administered.
+       * If it is 1, the address is locally administered
+       */
+       mac[0] |= BIT(1);
 
-       _rtw_memcpy(padapter->eeprompriv.mac_addr, mac, ETH_ALEN);
-       rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr, padapter->eeprompriv.mac_addr);
+       _rtw_memcpy(adapter_mac_addr(padapter), mac, ETH_ALEN);
+       rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));
 
        primary_padapter->pbuddy_adapter = padapter;
 
        res = _SUCCESS;
 
-       return padapter;
-
-
-error_rtw_drv_if2_init:
-
-       if(padapter)
+free_drv_sw:
+       if (res != _SUCCESS && padapter)
                rtw_free_drv_sw(padapter);
-
-       if (pnetdev)
-               rtw_free_netdev(pnetdev);
-
-       return NULL;
-
+free_adapter:
+       if (res != _SUCCESS && padapter) {
+               rtw_vmfree((u8 *)padapter, sizeof(*padapter));
+               padapter = NULL;
+       }
+exit:
+       return padapter;
 }
 
 void rtw_drv_if2_free(_adapter *if2)
 {
        _adapter *padapter = if2;
-       struct net_device *pnetdev = NULL;
 
        if (padapter == NULL)
                return;
 
-       pnetdev = padapter->pnetdev;
-
-#ifdef CONFIG_IOCTL_CFG80211
-       rtw_wdev_free(padapter->rtw_wdev);
-#endif /* CONFIG_IOCTL_CFG80211 */
-
-
        rtw_free_drv_sw(padapter);
 
-       rtw_free_netdev(pnetdev);
+       /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */
+       rtw_os_ndev_free(padapter);
 
+       rtw_vmfree((u8 *)padapter, sizeof(_adapter));
 }
 
 void rtw_drv_if2_stop(_adapter *if2)
@@ -2079,10 +2470,8 @@ void rtw_drv_if2_stop(_adapter *if2)
        if (padapter == NULL)
                return;
 
-       rtw_cancel_all_timer(padapter);
 
        if (padapter->bup == _TRUE) {
-               padapter->bDriverStopped = _TRUE;
                #ifdef CONFIG_XMIT_ACK
                if (padapter->xmitpriv.ack_tx)
                        rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP);
@@ -2097,9 +2486,138 @@ void rtw_drv_if2_stop(_adapter *if2)
 
                padapter->bup = _FALSE;
        }
+
+       /* cancel timer after thread stop */
+       rtw_cancel_all_timer(padapter);
 }
 #endif //end of CONFIG_CONCURRENT_MODE
 
+int rtw_os_ndevs_register(struct dvobj_priv *dvobj)
+{
+       int i, status = _SUCCESS;
+       struct registry_priv *regsty = dvobj_to_regsty(dvobj);
+       _adapter *adapter;
+
+#if defined(CONFIG_IOCTL_CFG80211)
+       if (rtw_cfg80211_dev_res_register(dvobj) != _SUCCESS) {
+               rtw_warn_on(1);
+               status = _FAIL;
+               goto exit;
+       }
+#endif
+
+       for (i = 0; i < dvobj->iface_nums; i++) {
+
+               if (i >= IFACE_ID_MAX) {
+                       DBG_871X_LEVEL(_drv_err_, "%s %d >= IFACE_ID_MAX\n", __func__, i);
+                       rtw_warn_on(1);
+                       continue;
+               }
+
+               adapter = dvobj->padapters[i];
+               if (adapter) {
+                       char *name;
+
+                       if (adapter->iface_id == IFACE_ID0)
+                               name = regsty->ifname;
+                       else if (adapter->iface_id == IFACE_ID1)
+                               name = regsty->if2name;
+                       else
+                               name = "wlan%d";
+
+                       #ifdef CONFIG_CONCURRENT_MODE
+                       switch (adapter->adapter_type) {
+                       case SECONDARY_ADAPTER:
+                               rtw_hook_if2_ops(adapter->pnetdev);
+                               break;
+                       #ifdef CONFIG_MULTI_VIR_IFACES
+                       case MAX_ADAPTER:
+                               rtw_hook_vir_if_ops(adapter->pnetdev);
+                               break;
+                       #endif
+                       }
+                       #endif /* CONFIG_CONCURRENT_MODE */
+
+                       status = rtw_os_ndev_register(adapter, name);
+
+                       if (status != _SUCCESS) {
+                               rtw_warn_on(1);
+                               break;
+                       }
+               }
+       }
+
+       if (status != _SUCCESS) {
+               for (; i >= 0; i--) {
+                       adapter = dvobj->padapters[i];
+                       if (adapter)
+                               rtw_os_ndev_unregister(adapter);
+               }
+       }
+
+#if defined(CONFIG_IOCTL_CFG80211)
+       if (status != _SUCCESS)
+               rtw_cfg80211_dev_res_unregister(dvobj);
+#endif
+exit:
+       return status;
+}
+
+void rtw_os_ndevs_unregister(struct dvobj_priv *dvobj)
+{
+       int i;
+       _adapter *adapter = NULL;
+
+       for (i = 0; i < dvobj->iface_nums; i++) {
+               adapter = dvobj->padapters[i];
+
+               if (adapter == NULL)
+                       continue;
+
+               rtw_os_ndev_unregister(adapter);
+       }
+
+#if defined(CONFIG_IOCTL_CFG80211)
+       rtw_cfg80211_dev_res_unregister(dvobj);
+#endif
+}
+
+/**
+ * rtw_os_ndevs_init - Allocate and register OS layer net devices and relating structures for @dvobj
+ * @dvobj: the dvobj on which this function applies
+ *
+ * Returns:
+ * _SUCCESS or _FAIL
+ */
+int rtw_os_ndevs_init(struct dvobj_priv *dvobj)
+{
+       int ret = _FAIL;
+
+       if (rtw_os_ndevs_alloc(dvobj) != _SUCCESS)
+               goto exit;
+
+       if (rtw_os_ndevs_register(dvobj) != _SUCCESS)
+               goto os_ndevs_free;
+
+       ret = _SUCCESS;
+
+os_ndevs_free:
+       if (ret != _SUCCESS)
+               rtw_os_ndevs_free(dvobj);
+exit:
+       return ret;
+}
+
+/**
+ * rtw_os_ndevs_deinit - Unregister and free OS layer net devices and relating structures for @dvobj
+ * @dvobj: the dvobj on which this function applies
+ */
+void rtw_os_ndevs_deinit(struct dvobj_priv *dvobj)
+{
+       rtw_os_ndevs_unregister(dvobj);
+       rtw_os_ndevs_free(dvobj);
+}
+
 #ifdef CONFIG_BR_EXT
 void netdev_br_init(struct net_device *netdev)
 {
@@ -2149,82 +2667,24 @@ void netdev_br_init(struct net_device *netdev)
 }
 #endif //CONFIG_BR_EXT
 
-static int _rtw_drv_register_netdev(_adapter *padapter, char *name)
-{
-       int ret = _SUCCESS;
-       struct net_device *pnetdev = padapter->pnetdev;
-
-       /* alloc netdev name */
-       rtw_init_netdev_name(pnetdev, name);
-
-       _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
-
-       /* Tell the network stack we exist */
-       if (register_netdev(pnetdev) != 0) {
-               DBG_871X(FUNC_NDEV_FMT "Failed!\n", FUNC_NDEV_ARG(pnetdev));
-               ret = _FAIL;
-               goto error_register_netdev;
-       }
-
-       DBG_871X("%s, MAC Address (if%d) = " MAC_FMT "\n", __FUNCTION__, (padapter->iface_id+1), MAC_ARG(pnetdev->dev_addr));
-
-       return ret;
-
-error_register_netdev:
-
-       if(padapter->iface_id > IFACE_ID0)
-       {
-               rtw_free_drv_sw(padapter);
-
-               rtw_free_netdev(pnetdev);
-       }
-
-       return ret;
-}
-
-int rtw_drv_register_netdev(_adapter *if1)
-{
-       int i, status = _SUCCESS;
-       struct dvobj_priv *dvobj = if1->dvobj;
-
-       if(dvobj->iface_nums < IFACE_ID_MAX)
-       {
-               for(i=0; i<dvobj->iface_nums; i++)
-               {
-                       _adapter *padapter = dvobj->padapters[i];
-
-                       if(padapter)
-                       {
-                               char *name;
-
-                               if(padapter->iface_id == IFACE_ID0)
-                                       name = if1->registrypriv.ifname;
-                               else if(padapter->iface_id == IFACE_ID1)
-                                       name = if1->registrypriv.if2name;
-                               else
-                                       name = "wlan%d";
-
-                               if((status = _rtw_drv_register_netdev(padapter, name)) != _SUCCESS) {
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       return status;
-}
-
 int _netdev_open(struct net_device *pnetdev)
 {
        uint status;
        _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
        struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+       HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(padapter);
+#endif //CONFIG_BT_COEXIST_SOCKET_TRX
 
        RT_TRACE(_module_os_intfs_c_,_drv_info_,("+871x_drv - dev_open\n"));
        DBG_871X("+871x_drv - drv_open, bup=%d\n", padapter->bup);
 
        padapter->netif_up = _TRUE;
 
+#ifdef CONFIG_PLATFORM_INTEL_BYT
+       rtw_sdio_set_power(1);
+#endif //CONFIG_PLATFORM_INTEL_BYT
+
        if(pwrctrlpriv->ps_flag == _TRUE){
                padapter->net_closed = _FALSE;
                goto netdev_open_normal_process;
@@ -2232,9 +2692,14 @@ int _netdev_open(struct net_device *pnetdev)
 
        if(padapter->bup == _FALSE)
        {
-               padapter->bDriverStopped = _FALSE;
-               padapter->bSurpriseRemoved = _FALSE;
-               padapter->bCardDisableWOHSM = _FALSE;
+#ifdef CONFIG_PLATFORM_INTEL_BYT
+               rtw_macaddr_cfg(adapter_mac_addr(padapter),  get_hal_mac_addr(padapter));
+               rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));
+               _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN);
+#endif //CONFIG_PLATFORM_INTEL_BYT
+
+               rtw_clr_surprise_removed(padapter);
+               rtw_clr_drv_stopped(padapter);
 
                status = rtw_hal_init(padapter);
                if (status ==_FAIL)
@@ -2245,10 +2710,6 @@ int _netdev_open(struct net_device *pnetdev)
 
                DBG_871X("MAC Address = "MAC_FMT"\n", MAC_ARG(pnetdev->dev_addr));
 
-#ifdef CONFIG_RF_GAIN_OFFSET
-               rtw_bb_rf_gain_offset(padapter);
-#endif //CONFIG_RF_GAIN_OFFSET
-
                status=rtw_start_drv_threads(padapter);
                if(status ==_FAIL)
                {
@@ -2273,6 +2734,12 @@ int _netdev_open(struct net_device *pnetdev)
 
                padapter->bup = _TRUE;
                pwrctrlpriv->bips_processing = _FALSE;
+
+#ifdef CONFIG_PLATFORM_INTEL_BYT
+#ifdef CONFIG_BT_COEXIST       
+               rtw_btcoex_IpsNotify(padapter, IPS_NONE);
+#endif // CONFIG_BT_COEXIST
+#endif //CONFIG_PLATFORM_INTEL_BYT             
        }
        padapter->net_closed = _FALSE;
 
@@ -2289,6 +2756,18 @@ int _netdev_open(struct net_device *pnetdev)
        netdev_br_init(pnetdev);
 #endif // CONFIG_BR_EXT
 
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+       if(is_primary_adapter(padapter) &&  _TRUE == pHalData->EEPROMBluetoothCoexist)
+       {
+               rtw_btcoex_init_socket(padapter);
+               padapter->coex_info.BtMgnt.ExtConfig.HCIExtensionVer = 0x04;
+               rtw_btcoex_SetHciVersion(padapter,0x04);
+       }
+       else
+               DBG_871X("CONFIG_BT_COEXIST: SECONDARY_ADAPTER\n");
+#endif //CONFIG_BT_COEXIST_SOCKET_TRX
+
+
 netdev_open_normal_process:
 
        #ifdef CONFIG_CONCURRENT_MODE
@@ -2322,6 +2801,13 @@ int netdev_open(struct net_device *pnetdev)
 {
        int ret;
        _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
+       struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
+
+       if (pwrctrlpriv->bInSuspend == _TRUE)
+       {
+               DBG_871X("+871x_drv - drv_open, bInSuspend=%d\n", pwrctrlpriv->bInSuspend);
+               return 0;
+       }
 
        _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL);
        ret = _netdev_open(pnetdev);
@@ -2341,8 +2827,7 @@ int  ips_netdrv_open(_adapter *padapter)
        DBG_871X("===> %s.........\n",__FUNCTION__);
 
 
-       padapter->bDriverStopped = _FALSE;
-       padapter->bCardDisableWOHSM = _FALSE;
+       rtw_clr_drv_stopped(padapter);
        //padapter->bup = _TRUE;
 
        status = rtw_hal_init(padapter);
@@ -2352,10 +2837,6 @@ int  ips_netdrv_open(_adapter *padapter)
                goto netdev_open_error;
        }
 
-#ifdef CONFIG_RF_GAIN_OFFSET
-       rtw_bb_rf_gain_offset(padapter);
-#endif //CONFIG_RF_GAIN_OFFSET
-
        if (padapter->intf_start)
        {
                padapter->intf_start(padapter);
@@ -2391,7 +2872,7 @@ int rtw_ips_pwr_up(_adapter *padapter)
        if (psrtpriv->silent_reset_inprogress == _TRUE)
 #endif//#ifdef DBG_CONFIG_ERROR_DETECT         
 #endif //defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_FWLPS_IN_IPS)
-       rtw_reset_drv_sw(padapter);
+               rtw_reset_drv_sw(padapter);
 
        result = ips_netdrv_open(padapter);
 
@@ -2407,11 +2888,9 @@ void rtw_ips_pwr_down(_adapter *padapter)
        u32 start_time = rtw_get_current_time();
        DBG_871X("===> rtw_ips_pwr_down...................\n");
 
-       padapter->bCardDisableWOHSM = _TRUE;
        padapter->net_closed = _TRUE;
 
        rtw_ips_dev_unload(padapter);
-       padapter->bCardDisableWOHSM = _FALSE;
        DBG_871X("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time));
 }
 #endif
@@ -2440,127 +2919,27 @@ void rtw_ips_dev_unload(_adapter *padapter)
                }
        }
 
-       if(padapter->bSurpriseRemoved == _FALSE)
-       {
+       if (!rtw_is_surprise_removed(padapter))
                rtw_hal_deinit(padapter);
-       }
-
-}
-
-#ifdef CONFIG_RF_GAIN_OFFSET
-u32 Array_kfreemap[] = { 
-0xf8,0xe,
-0xf6,0xc,
-0xf4,0xa,
-0xf2,0x8,
-0xf0,0x6,
-0xf3,0x4,
-0xf5,0x2,
-0xf7,0x0,
-0xf9,0x0,
-0xfc,0x0,
-};
 
-void rtw_bb_rf_gain_offset(_adapter *padapter)
-{
-       u8              value = padapter->eeprompriv.EEPROMRFGainOffset;
-       u8              tmp = 0x3e;
-       u32     res,i=0;
-       u4Byte     ArrayLen    = sizeof(Array_kfreemap)/sizeof(u32);
-       pu4Byte    Array           = Array_kfreemap;
-       u4Byte v1=0,v2=0,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 (value & BIT4) {
-               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, 0x7f, 0xffffffff);
-                       res &= 0xfff87fff;
-                       DBG_871X("Offset RF Gain. before reg 0x7f=0x%08x\n",res);
-                       //res &= 0xfff87fff;
-                       for (i = 0; i < ArrayLen; i += 2 )
-                       {
-                               v1 = Array[i];
-                               v2 = Array[i+1];
-                                if ( v1 == padapter->eeprompriv.EEPROMRFGainVal )
-                                {
-                                               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);
-                       PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target);
-
-                       //res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15;
-                       //rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res);
-                       res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
-                       DBG_871X("Offset RF Gain. After reg 0x7f=0x%08x\n",res);
-               }
-               else
-               {
-                       DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x    != 0xff, didn't run Kfree\n",padapter->eeprompriv.EEPROMRFGainVal);
-               }
-       } else {
-               DBG_871X("Using the default RF gain.\n");
-       }
-#else
-       if (!(value & 0x01)) {
-               //DBG_871X("Offset RF Gain.\n");
-               res = rtw_hal_read_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, 0xffffffff);
-               value &= tmp;
-               res = value << 14;
-               rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res);
-       } else {
-               DBG_871X("Using the default RF gain.\n");
-       }
-#endif
-       
 }
-#endif //CONFIG_RF_GAIN_OFFSET
 
 
 int pm_netdev_open(struct net_device *pnetdev,u8 bnormal)
 {
        int status = 0;
 
+       _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
 
        if (_TRUE == bnormal)
-               status = netdev_open(pnetdev);
+       {
+               _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL);
+               status = _netdev_open(pnetdev);
+               _exit_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL);
+       }       
 #ifdef CONFIG_IPS
        else
-               status =  (_SUCCESS == ips_netdrv_open((_adapter *)rtw_netdev_priv(pnetdev)))?(0):(-1);
+               status =  (_SUCCESS == ips_netdrv_open(padapter))?(0):(-1);
 #endif
 
        return status;
@@ -2570,9 +2949,14 @@ static int netdev_close(struct net_device *pnetdev)
 {
        _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
        struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+       HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(padapter);
+#endif //CONFIG_BT_COEXIST_SOCKET_TRX
 
        RT_TRACE(_module_os_intfs_c_,_drv_info_,("+871x_drv - drv_close\n"));
 
+#ifndef CONFIG_PLATFORM_INTEL_BYT
        if(pwrctl->bInternalAutoSuspend == _TRUE)
        {
                //rtw_pwr_wakeup(padapter);
@@ -2581,18 +2965,18 @@ static int netdev_close(struct net_device *pnetdev)
        }
        padapter->net_closed = _TRUE;
        padapter->netif_up = _FALSE;
+       pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
 
-/*     if(!padapter->hw_init_completed)
-       {
-               DBG_871X("(1)871x_drv - drv_close, bup=%d, hw_init_completed=%d\n", padapter->bup, padapter->hw_init_completed);
+/*     if (!rtw_is_hw_init_completed(padapter)) {
+               DBG_871X("(1)871x_drv - drv_close, bup=%d, hw_init_completed=%s\n", padapter->bup, rtw_is_hw_init_completed(padapter)?"_TRUE":"_FALSE");
 
-               padapter->bDriverStopped = _TRUE;
+               rtw_set_drv_stopped(padapter);
 
                rtw_dev_unload(padapter);
        }
        else*/
        if(pwrctl->rf_pwrstate == rf_on){
-               DBG_871X("(2)871x_drv - drv_close, bup=%d, hw_init_completed=%d\n", padapter->bup, padapter->hw_init_completed);
+               DBG_871X("(2)871x_drv - drv_close, bup=%d, hw_init_completed=%s\n", padapter->bup, rtw_is_hw_init_completed(padapter)?"_TRUE":"_FALSE");
 
                //s1.
                if(pnetdev)
@@ -2615,54 +2999,386 @@ static int netdev_close(struct net_device *pnetdev)
                rtw_led_control(padapter, LED_CTL_POWER_OFF);
        }
 
-#ifdef CONFIG_BR_EXT
-       //if (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE))
-       {
-               //void nat25_db_cleanup(_adapter *priv);
-               nat25_db_cleanup(padapter);
+#ifdef CONFIG_BR_EXT
+       //if (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE))
+       {
+               //void nat25_db_cleanup(_adapter *priv);
+               nat25_db_cleanup(padapter);
+       }
+#endif // CONFIG_BR_EXT
+
+#ifdef CONFIG_P2P
+       if (!rtw_p2p_chk_role(&padapter->wdinfo, P2P_ROLE_DISABLE))
+               rtw_p2p_enable(padapter, P2P_ROLE_DISABLE);
+#endif //CONFIG_P2P
+
+#ifdef CONFIG_IOCTL_CFG80211
+       rtw_scan_abort(padapter);
+       rtw_cfg80211_wait_scan_req_empty(padapter, 200);
+       adapter_wdev_data(padapter)->bandroid_scan = _FALSE;
+       //padapter->rtw_wdev->iftype = NL80211_IFTYPE_MONITOR; //set this at the end
+#endif //CONFIG_IOCTL_CFG80211
+
+#ifdef CONFIG_WAPI_SUPPORT
+       rtw_wapi_disable_tx(padapter);
+#endif
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+       if(is_primary_adapter(padapter) &&  _TRUE == pHalData->EEPROMBluetoothCoexist)
+               rtw_btcoex_close_socket(padapter);
+       else
+               DBG_871X("CONFIG_BT_COEXIST: SECONDARY_ADAPTER\n");
+#endif //CONFIG_BT_COEXIST_SOCKET_TRX
+#else //!CONFIG_PLATFORM_INTEL_BYT
+
+       if (pwrctl->bInSuspend == _TRUE)
+       {
+               DBG_871X("+871x_drv - drv_close, bInSuspend=%d\n", pwrctl->bInSuspend);
+               return 0;
+       }
+
+       rtw_scan_abort(padapter); // stop scanning process before wifi is going to down
+       #ifdef CONFIG_IOCTL_CFG80211
+       rtw_cfg80211_wait_scan_req_empty(padapter, 200);
+       #endif
+
+       DBG_871X("netdev_close, bips_processing=%d\n", pwrctl->bips_processing);
+       while (pwrctl->bips_processing == _TRUE) // waiting for ips_processing done before call rtw_dev_unload()
+               rtw_msleep_os(1);       
+
+       rtw_dev_unload(padapter);
+       rtw_sdio_set_power(0);
+
+#endif //!CONFIG_PLATFORM_INTEL_BYT
+
+       RT_TRACE(_module_os_intfs_c_,_drv_info_,("-871x_drv - drv_close\n"));
+       DBG_871X("-871x_drv - drv_close, bup=%d\n", padapter->bup);
+
+       return 0;
+
+}
+
+int pm_netdev_close(struct net_device *pnetdev,u8 bnormal)
+{
+       int status = 0;
+
+       status = netdev_close(pnetdev);
+
+       return status;
+}
+
+void rtw_ndev_destructor(struct net_device *ndev)
+{
+       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+
+#ifdef CONFIG_IOCTL_CFG80211
+       if (ndev->ieee80211_ptr)
+               rtw_mfree((u8 *)ndev->ieee80211_ptr, sizeof(struct wireless_dev));
+#endif
+       free_netdev(ndev);
+}
+
+#ifdef CONFIG_ARP_KEEP_ALIVE
+struct route_info {
+    struct in_addr dst_addr;
+    struct in_addr src_addr;
+    struct in_addr gateway;
+    unsigned int dev_index;
+};
+
+static void parse_routes(struct nlmsghdr *nl_hdr, struct route_info *rt_info)
+{
+    struct rtmsg *rt_msg;
+    struct rtattr *rt_attr;
+    int rt_len;
+
+    rt_msg = (struct rtmsg *) NLMSG_DATA(nl_hdr);
+    if ((rt_msg->rtm_family != AF_INET) || (rt_msg->rtm_table != RT_TABLE_MAIN))
+        return;
+
+    rt_attr = (struct rtattr *) RTM_RTA(rt_msg);
+    rt_len = RTM_PAYLOAD(nl_hdr);
+
+    for (; RTA_OK(rt_attr, rt_len); rt_attr = RTA_NEXT(rt_attr, rt_len)) 
+       {
+        switch (rt_attr->rta_type) {
+        case RTA_OIF:
+               rt_info->dev_index = *(int *) RTA_DATA(rt_attr);
+            break;
+        case RTA_GATEWAY:
+            rt_info->gateway.s_addr = *(u_int *) RTA_DATA(rt_attr);
+            break;
+        case RTA_PREFSRC:
+            rt_info->src_addr.s_addr = *(u_int *) RTA_DATA(rt_attr);
+            break;
+        case RTA_DST:
+            rt_info->dst_addr.s_addr = *(u_int *) RTA_DATA(rt_attr);
+            break;
+        }
+    }
+}
+
+static int route_dump(u32 *gw_addr ,int* gw_index)
+{
+       int err = 0;
+       struct socket *sock;
+       struct {
+               struct nlmsghdr nlh;
+               struct rtgenmsg g;
+       } req;
+       struct msghdr msg;
+       struct iovec iov;
+       struct sockaddr_nl nladdr;
+       mm_segment_t oldfs;
+       char *pg;
+       int size = 0;
+
+       err = sock_create(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, &sock);
+       if (err)
+       {
+               printk( ": Could not create a datagram socket, error = %d\n", -ENXIO);
+               return err;
+       }
+       
+       memset(&nladdr, 0, sizeof(nladdr));
+       nladdr.nl_family = AF_NETLINK;
+
+       req.nlh.nlmsg_len = sizeof(req);
+       req.nlh.nlmsg_type = RTM_GETROUTE;
+       req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+       req.nlh.nlmsg_pid = 0;
+       req.g.rtgen_family = AF_INET;
+
+       iov.iov_base = &req;
+       iov.iov_len = sizeof(req);
+
+       msg.msg_name = &nladdr;
+       msg.msg_namelen = sizeof(nladdr);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+       /* referece:sock_xmit in kernel code
+        * WRITE for sock_sendmsg, READ for sock_recvmsg
+        * third parameter for msg_iovlen
+        * last parameter for iov_len
+        */
+       iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, sizeof(req));
+#else
+       msg.msg_iov = &iov;
+       msg.msg_iovlen = 1;
+#endif
+       msg.msg_control = NULL;
+       msg.msg_controllen = 0;
+       msg.msg_flags = MSG_DONTWAIT;
+
+       oldfs = get_fs(); set_fs(KERNEL_DS);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+       err = sock_sendmsg(sock, &msg);
+#else
+       err = sock_sendmsg(sock, &msg, sizeof(req));
+#endif
+       set_fs(oldfs);
+
+       if (err < 0)
+               goto out_sock;
+
+       pg = (char *) __get_free_page(GFP_KERNEL);
+       if (pg == NULL) {
+               err = -ENOMEM;
+               goto out_sock;
+       }
+
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+restart:
+#endif
+
+       for (;;) 
+       {
+               struct nlmsghdr *h;
+
+               iov.iov_base = pg;
+               iov.iov_len = PAGE_SIZE;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+               iov_iter_init(&msg.msg_iter, READ, &iov, 1, PAGE_SIZE);
+#endif
+
+               oldfs = get_fs(); set_fs(KERNEL_DS);
+               err = sock_recvmsg(sock, &msg, PAGE_SIZE, MSG_DONTWAIT);
+               set_fs(oldfs);
+
+               if (err < 0)
+                       goto out_sock_pg;
+
+               if (msg.msg_flags & MSG_TRUNC) {
+                       err = -ENOBUFS;
+                       goto out_sock_pg;
+               }
+
+               h = (struct nlmsghdr*) pg;
+               
+               while (NLMSG_OK(h, err)) 
+               {
+                       struct route_info rt_info;
+                       if (h->nlmsg_type == NLMSG_DONE) {
+                               err = 0;
+                               goto done;
+                       }
+
+                       if (h->nlmsg_type == NLMSG_ERROR) {
+                               struct nlmsgerr *errm = (struct nlmsgerr*) NLMSG_DATA(h);
+                               err = errm->error;
+                               printk( "NLMSG error: %d\n", errm->error);
+                               goto done;
+                       }
+
+                       if (h->nlmsg_type == RTM_GETROUTE)
+                       {
+                               printk( "RTM_GETROUTE: NLMSG: %d\n", h->nlmsg_type);
+                       }
+                       if (h->nlmsg_type != RTM_NEWROUTE) {
+                               printk( "NLMSG: %d\n", h->nlmsg_type);
+                               err = -EINVAL;
+                               goto done;
+                       }
+
+                       memset(&rt_info, 0, sizeof(struct route_info));
+                       parse_routes(h, &rt_info);
+                       if(!rt_info.dst_addr.s_addr && rt_info.gateway.s_addr && rt_info.dev_index)
+                       {
+                               *gw_addr = rt_info.gateway.s_addr;
+                               *gw_index = rt_info.dev_index;
+                                       
+                       }
+                       h = NLMSG_NEXT(h, err);
+               }
+
+               if (err) 
+               {
+                       printk( "!!!Remnant of size %d %d %d\n", err, h->nlmsg_len, h->nlmsg_type);
+                       err = -EINVAL;
+                       break;
+               }
        }
-#endif // CONFIG_BR_EXT
 
-#ifdef CONFIG_P2P
-       rtw_p2p_enable(padapter, P2P_ROLE_DISABLE);
-#endif //CONFIG_P2P
+done:
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+       if (!err && req.g.rtgen_family == AF_INET) {
+               req.g.rtgen_family = AF_INET6;
 
-#ifdef CONFIG_IOCTL_CFG80211
-       rtw_scan_abort(padapter);
-       adapter_wdev_data(padapter)->bandroid_scan = _FALSE;
-       //padapter->rtw_wdev->iftype = NL80211_IFTYPE_MONITOR; //set this at the end
-#endif //CONFIG_IOCTL_CFG80211
+               iov.iov_base = &req;
+               iov.iov_len = sizeof(req);
 
-#ifdef CONFIG_WAPI_SUPPORT
-       rtw_wapi_disable_tx(padapter);
+               msg.msg_name = &nladdr;
+               msg.msg_namelen = sizeof(nladdr);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+               iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, sizeof(req));
+#else
+               msg.msg_iov = &iov;
+               msg.msg_iovlen = 1;
 #endif
+               msg.msg_control = NULL;
+               msg.msg_controllen = 0;
+               msg.msg_flags=MSG_DONTWAIT;
 
-       RT_TRACE(_module_os_intfs_c_,_drv_info_,("-871x_drv - drv_close\n"));
-       DBG_871X("-871x_drv - drv_close, bup=%d\n", padapter->bup);
+               oldfs = get_fs(); set_fs(KERNEL_DS);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+               err = sock_sendmsg(sock, &msg);
+#else
+               err = sock_sendmsg(sock, &msg, sizeof(req));
+#endif
+               set_fs(oldfs);
 
-       return 0;
+               if (err > 0)
+                       goto restart;
+       }
+#endif
+
+out_sock_pg:
+       free_page((unsigned long) pg);
 
+out_sock:
+       sock_release(sock);
+       return err;
 }
 
-int pm_netdev_close(struct net_device *pnetdev,u8 bnormal)
+static int arp_query(unsigned char *haddr, u32 paddr,
+             struct net_device *dev)
 {
-       int status = 0;
+       struct neighbour *neighbor_entry;
+       int     ret = 0;
 
-       status = netdev_close(pnetdev);
+       neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev);
 
-       return status;
+       if (neighbor_entry != NULL) {
+               neighbor_entry->used = jiffies;
+               if (neighbor_entry->nud_state & NUD_VALID) {
+                       _rtw_memcpy(haddr, neighbor_entry->ha, dev->addr_len);
+                       ret = 1;
+               }
+               neigh_release(neighbor_entry);
+       }
+       return ret;
 }
 
-void rtw_ndev_destructor(struct net_device *ndev)
+static int get_defaultgw(u32 *ip_addr ,char mac[])
 {
-       DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
+       int gw_index = 0; // oif device index
+       struct net_device *gw_dev = NULL; //oif device
+       
+       route_dump(ip_addr, &gw_index);
 
-#ifdef CONFIG_IOCTL_CFG80211
-       if (ndev->ieee80211_ptr)
-               rtw_mfree((u8 *)ndev->ieee80211_ptr, sizeof(struct wireless_dev));
-#endif
-       free_netdev(ndev);
+       if( !(*ip_addr) || !gw_index )
+       {
+               //DBG_871X("No default GW \n");
+               return -1;
+       }
+
+       gw_dev = dev_get_by_index(&init_net, gw_index);
+
+       if(gw_dev == NULL)
+       {
+               //DBG_871X("get Oif Device Fail \n");
+               return -1;
+       }
+       
+       if(!arp_query(mac, *ip_addr, gw_dev))
+       {
+               //DBG_871X( "arp query failed\n");
+               dev_put(gw_dev);
+               return -1;
+               
+       }
+       dev_put(gw_dev);
+       
+       return 0;
+}
+
+int    rtw_gw_addr_query(_adapter *padapter)
+{
+       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
+       struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+       u32 gw_addr = 0; // default gw address
+       unsigned char gw_mac[32] = {0}; // default gw mac
+       int i;
+       int res;
+
+       res = get_defaultgw(&gw_addr, gw_mac);
+       if(!res)
+       {
+               pmlmepriv->gw_ip[0] = gw_addr&0xff;
+               pmlmepriv->gw_ip[1] = (gw_addr&0xff00)>>8;
+               pmlmepriv->gw_ip[2] = (gw_addr&0xff0000)>>16;
+               pmlmepriv->gw_ip[3] = (gw_addr&0xff000000)>>24;
+               _rtw_memcpy(pmlmepriv->gw_mac_addr, gw_mac, 6);
+               DBG_871X("%s Gateway Mac:\t" MAC_FMT "\n", __FUNCTION__, MAC_ARG(pmlmepriv->gw_mac_addr));
+               DBG_871X("%s Gateway IP:\t" IP_FMT "\n", __FUNCTION__, IP_ARG(pmlmepriv->gw_ip));
+       }
+       else
+       {
+               DBG_871X("Get Gateway IP/MAC fail!\n");
+       }
+
+       return res;
 }
+#endif
 
 void rtw_dev_unload(PADAPTER padapter)
 {
@@ -2670,6 +3386,8 @@ void rtw_dev_unload(PADAPTER padapter)
        struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
        struct dvobj_priv *pobjpriv = padapter->dvobj;
        struct debug_priv *pdbgpriv = &pobjpriv->drv_dbg;
+       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+       u8 cnt = 0;
 
        RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+%s\n",__FUNCTION__));
 
@@ -2677,7 +3395,7 @@ void rtw_dev_unload(PADAPTER padapter)
        {
                DBG_871X("===> %s\n",__FUNCTION__);
 
-               padapter->bDriverStopped = _TRUE;
+               rtw_set_drv_stopped(padapter);
                #ifdef CONFIG_XMIT_ACK
                if (padapter->xmitpriv.ack_tx)
                        rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP);
@@ -2690,20 +3408,32 @@ void rtw_dev_unload(PADAPTER padapter)
 
                if (!pwrctl->bInternalAutoSuspend)
                        rtw_stop_drv_threads(padapter);
-               
+
+               while(ATOMIC_READ(&(pcmdpriv->cmdthd_running)) == _TRUE){
+                       if (cnt > 5) {
+                               DBG_871X("stop cmdthd timeout\n");
+                               break;
+                       } else {
+                               cnt ++;
+                               DBG_871X("cmdthd is running(%d)\n", cnt);
+                               rtw_msleep_os(10);
+                       }
+               }
+
                RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("@ %s: stop thread complete!\n",__FUNCTION__));
 
                //check the status of IPS
                if(rtw_hal_check_ips_status(padapter) == _TRUE || pwrctl->rf_pwrstate == rf_off) { //check HW status and SW state
                        DBG_871X_LEVEL(_drv_always_, "%s: driver in IPS-FWLPS\n", __func__);
                        pdbgpriv->dbg_dev_unload_inIPS_cnt++;
-                       LeaveAllPowerSaveMode(padapter);
                } else {
                        DBG_871X_LEVEL(_drv_always_, "%s: driver not in IPS\n", __func__);
                }
 
-               if (padapter->bSurpriseRemoved == _FALSE)
-               {
+               if (!rtw_is_surprise_removed(padapter)) {
+#ifdef CONFIG_BT_COEXIST
+                       rtw_btcoex_IpsNotify(padapter, pwrctl->ips_mode_req);
+#endif
 #ifdef CONFIG_WOWLAN
                        if (pwrctl->bSupportRemoteWakeup == _TRUE && 
                                pwrctl->wowlan_mode ==_TRUE) {
@@ -2715,7 +3445,7 @@ void rtw_dev_unload(PADAPTER padapter)
                                //amy modify 20120221 for power seq is different between driver open and ips
                                rtw_hal_deinit(padapter);
                        }
-                       padapter->bSurpriseRemoved = _TRUE;
+                       rtw_set_surprise_removed(padapter);
                }
                RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("@ %s: deinit hal complelt!\n",__FUNCTION__));
 
@@ -2727,23 +3457,29 @@ void rtw_dev_unload(PADAPTER padapter)
                RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("%s: bup==_FALSE\n",__FUNCTION__));
                DBG_871X("%s: bup==_FALSE\n",__FUNCTION__);
        }
-       
+
+       /* cancel timer after thread stop */
+       rtw_cancel_all_timer(padapter);
        RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-%s\n",__FUNCTION__));
 }
 
-#ifdef CONFIG_SUSPEND_REFINE
 int rtw_suspend_free_assoc_resource(_adapter *padapter)
 {
        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
        struct net_device *pnetdev = padapter->pnetdev;
+#ifdef CONFIG_P2P
        struct wifidirect_info* pwdinfo = &padapter->wdinfo;
+#endif // CONFIG_P2P
 
        DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter));
 
        if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) {
                if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)
                        && check_fwstate(pmlmepriv, _FW_LINKED)
-                       && rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
+#ifdef CONFIG_P2P
+                       && rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
+#endif // CONFIG_P2P
+                       )
                {
                        DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__,
                                        pmlmepriv->cur_network.network.Ssid.Ssid,
@@ -2763,7 +3499,7 @@ int rtw_suspend_free_assoc_resource(_adapter *padapter)
        #ifdef CONFIG_AP_MODE
        else if(check_fwstate(pmlmepriv, WIFI_AP_STATE))        
        {
-               rtw_sta_flush(padapter);
+               rtw_sta_flush(padapter, _TRUE);
        }
        #endif
                
@@ -2774,10 +3510,13 @@ int rtw_suspend_free_assoc_resource(_adapter *padapter)
 #ifdef CONFIG_AUTOSUSPEND
        if(is_primary_adapter(padapter) && (!adapter_to_pwrctl(padapter)->bInternalAutoSuspend ))
 #endif
-       rtw_free_network_queue(padapter, _TRUE);
+               rtw_free_network_queue(padapter, _TRUE);
 
-       if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
+               DBG_871X_LEVEL(_drv_always_, "%s: fw_under_survey\n", __func__);
                rtw_indicate_scan_done(padapter, 1);
+               clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
+       }
 
        if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
        {
@@ -2806,17 +3545,16 @@ int rtw_suspend_wow(_adapter *padapter)
        int ret = _SUCCESS;
 
        DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter));
-       
-       if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-               pwrpriv->wowlan_mode = _TRUE;
-       } else if (pwrpriv->wowlan_pno_enable == _TRUE) {
-               pwrpriv->wowlan_mode |= pwrpriv->wowlan_pno_enable;
-       }
+
 
        DBG_871X("wowlan_mode: %d\n", pwrpriv->wowlan_mode);
        DBG_871X("wowlan_pno_enable: %d\n", pwrpriv->wowlan_pno_enable);
+#ifdef CONFIG_P2P_WOWLAN
+       DBG_871X("wowlan_p2p_enable: %d\n", pwrpriv->wowlan_p2p_enable);
+#endif
        
        if (pwrpriv->wowlan_mode == _TRUE) {
+               
                if(pnetdev)
                        rtw_netif_stop_queue(pnetdev);  
                #ifdef CONFIG_CONCURRENT_MODE
@@ -2825,24 +3563,22 @@ int rtw_suspend_wow(_adapter *padapter)
                        rtw_netif_stop_queue(pbuddy_netdev);
                }
                #endif//CONFIG_CONCURRENT_MODE
+               // 0. Power off LED
+               rtw_led_control(padapter, LED_CTL_POWER_OFF);
                // 1. stop thread
-               padapter->bDriverStopped = _TRUE;       //for stop thread
+               rtw_set_drv_stopped(padapter);  /*for stop thread*/
                rtw_stop_drv_threads(padapter);
-               padapter->bDriverStopped = _FALSE;      //for 32k command
-
                #ifdef CONFIG_CONCURRENT_MODE   
-               if (rtw_buddy_adapter_up(padapter)) {
-                       padapter->pbuddy_adapter->bDriverStopped = _TRUE;       //for stop thread
+               if (rtw_buddy_adapter_up(padapter))
                        rtw_stop_drv_threads(padapter->pbuddy_adapter);
-                       padapter->pbuddy_adapter->bDriverStopped = _FALSE;      //for 32k command
-               }
-               #endif // CONFIG_CONCURRENT_MODE
+               #endif /*CONFIG_CONCURRENT_MODE*/
+               rtw_clr_drv_stopped(padapter);  /*for 32k command*/
 
-               //#ifdef CONFIG_POWER_SAVING
+               //#ifdef CONFIG_LPS
                //rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "WOWLAN");
                //#endif
 
-#ifdef CONFIG_SDIO_HCI
+#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
                // 2. disable interrupt
                if (padapter->intf_stop) {
                        padapter->intf_stop(padapter);
@@ -2856,8 +3592,7 @@ int rtw_suspend_wow(_adapter *padapter)
                #endif
 
                // 2.1 clean interupt
-               if (padapter->HalFunc.clear_interrupt)
-                       padapter->HalFunc.clear_interrupt(padapter);
+               rtw_hal_clear_interrupt(padapter);
 #endif //CONFIG_SDIO_HCI
 
                // 2.2 free irq
@@ -2873,7 +3608,7 @@ int rtw_suspend_wow(_adapter *padapter)
                #endif
 
                poidparam.subcode = WOWLAN_ENABLE;
-               padapter->HalFunc.SetHwRegHandler(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam);
+               rtw_hal_set_hwreg(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam);
                if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) {
                        if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)
                                && check_fwstate(pmlmepriv, _FW_LINKED))
@@ -2907,56 +3642,23 @@ int rtw_suspend_wow(_adapter *padapter)
                        rtw_suspend_free_assoc_resource(padapter->pbuddy_adapter);
                }
                #endif  
-               
-               #ifdef CONFIG_POWER_SAVING
-               if(pwrpriv->wowlan_pno_enable)
-                       DBG_871X_LEVEL(_drv_always_, "%s: pno: %d\n", __func__, pwrpriv->wowlan_pno_enable);
+
+               if(pwrpriv->wowlan_pno_enable) {
+                       DBG_871X_LEVEL(_drv_always_, "%s: pno: %d\n", __func__,
+                                       pwrpriv->wowlan_pno_enable);
+#ifdef CONFIG_FWLPS_IN_IPS
+                       rtw_set_fw_in_ips_mode(padapter, _TRUE);
+#endif
+               }
+               #ifdef CONFIG_LPS
                else
-                       rtw_set_ps_mode(padapter, PS_MODE_DTIM, 0, 0, "WOWLAN");
-               #endif
+                       rtw_set_ps_mode(padapter, PS_MODE_MAX, 0, 0, "WOWLAN");
+               #endif //#ifdef CONFIG_LPS
 
        }
        else
        {
-               if(pnetdev){
-                       netif_carrier_off(pnetdev);
-                       rtw_netif_stop_queue(pnetdev);  
-               }
-               #ifdef CONFIG_CONCURRENT_MODE
-               if(pbuddy_netdev){
-                       netif_carrier_off(pbuddy_netdev);
-                       rtw_netif_stop_queue(pbuddy_netdev);
-               }
-               #endif//CONFIG_CONCURRENT_MODE
-               
-               rtw_suspend_free_assoc_resource(padapter);
-
-               #ifdef CONFIG_CONCURRENT_MODE
-               if(rtw_buddy_adapter_up(padapter)){
-                       rtw_suspend_free_assoc_resource(padapter->pbuddy_adapter);
-               }
-               #endif//CONFIG_CONCURRENT_MODE
-               rtw_led_control(padapter, LED_CTL_POWER_OFF);
-
-
-               if ((rtw_hal_check_ips_status(padapter) == _TRUE)
-                       || (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off))
-               {
-                       DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR #### driver in IPS ####ERROR###!!!\n", __FUNCTION__);       
-               
-               }
-
-
-               #ifdef CONFIG_CONCURRENT_MODE
-               if(rtw_buddy_adapter_up(padapter)){
-                       rtw_dev_unload(padapter->pbuddy_adapter);
-               }
-               #endif
-               rtw_dev_unload(padapter);
-
-               //sdio_deinit(adapter_to_dvobj(padapter));
-               if(padapter->intf_deinit)
-                       padapter->intf_deinit(adapter_to_dvobj(padapter));
+               DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR ### wowlan_mode=%d\n", __FUNCTION__, pwrpriv->wowlan_mode); 
        }
        DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter));
        return ret;
@@ -2971,9 +3673,9 @@ int rtw_suspend_ap_wow(_adapter *padapter)
        struct net_device *pnetdev = padapter->pnetdev;
        #ifdef CONFIG_CONCURRENT_MODE
        struct net_device *pbuddy_netdev;
-       #endif  
+       #endif
        struct dvobj_priv *psdpriv = padapter->dvobj;
-       struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;        
+       struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
        struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
        struct wowlan_ioctl_param poidparam;
        u8 ps_mode;
@@ -2986,7 +3688,7 @@ int rtw_suspend_ap_wow(_adapter *padapter)
        DBG_871X("wowlan_ap_mode: %d\n", pwrpriv->wowlan_ap_mode);
        
        if(pnetdev)
-               rtw_netif_stop_queue(pnetdev);  
+               rtw_netif_stop_queue(pnetdev);
        #ifdef CONFIG_CONCURRENT_MODE
        if (rtw_buddy_adapter_up(padapter)) {
                pbuddy_netdev = padapter->pbuddy_adapter->pnetdev;
@@ -2994,23 +3696,18 @@ int rtw_suspend_ap_wow(_adapter *padapter)
                rtw_netif_stop_queue(pbuddy_netdev);
        }
        #endif//CONFIG_CONCURRENT_MODE
+       // 0. Power off LED
+       rtw_led_control(padapter, LED_CTL_POWER_OFF);
        // 1. stop thread
-       padapter->bDriverStopped = _TRUE;       //for stop thread
+       rtw_set_drv_stopped(padapter);  /*for stop thread*/
        rtw_stop_drv_threads(padapter);
-       padapter->bDriverStopped = _FALSE;      //for 32k command
-
        #ifdef CONFIG_CONCURRENT_MODE   
-       if(rtw_buddy_adapter_up(padapter)){
-               padapter->pbuddy_adapter->bDriverStopped = _TRUE;       //for stop thread
+       if (rtw_buddy_adapter_up(padapter))
                rtw_stop_drv_threads(padapter->pbuddy_adapter);
-               padapter->pbuddy_adapter->bDriverStopped = _FALSE;      //for 32k command
-       }
-       #endif // CONFIG_CONCURRENT_MODE
-
-       //#ifdef CONFIG_POWER_SAVING
-       //rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "WOWLAN");
-       //#endif
+       #endif /* CONFIG_CONCURRENT_MODE */
+       rtw_clr_drv_stopped(padapter);  /*for 32k command*/
 
+#ifdef CONFIG_SDIO_HCI
        // 2. disable interrupt
        rtw_hal_disable_interrupt(padapter); // It need wait for leaving 32K.
 
@@ -3021,11 +3718,10 @@ int rtw_suspend_ap_wow(_adapter *padapter)
        #endif
 
        // 2.1 clean interupt
-       if (padapter->HalFunc.clear_interrupt)
-               padapter->HalFunc.clear_interrupt(padapter);
+       rtw_hal_clear_interrupt(padapter);
+#endif //CONFIG_SDIO_HCI
 
        // 2.2 free irq
-       //sdio_free_irq(adapter_to_dvobj(padapter));
        if(padapter->intf_free_irq)
                padapter->intf_free_irq(adapter_to_dvobj(padapter));
 
@@ -3034,14 +3730,13 @@ int rtw_suspend_ap_wow(_adapter *padapter)
                DBG_871X(" ### PORT SWITCH ### \n");
                rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
        }
-       #endif          
-               
+       #endif
+
        poidparam.subcode = WOWLAN_AP_ENABLE;
-       padapter->HalFunc.SetHwRegHandler(padapter,
-                                       HW_VAR_AP_WOWLAN,(u8 *)&poidparam);
+       rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam);
 
        DBG_871X_LEVEL(_drv_always_, "%s: wowmode suspending\n", __func__);
-               
+
 #ifdef CONFIG_CONCURRENT_MODE
        if (check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE) {
                if (rtw_get_ch_setting_union(padapter->pbuddy_adapter, &ch, &bw, &offset) != 0) {
@@ -3066,11 +3761,9 @@ int rtw_suspend_ap_wow(_adapter *padapter)
        }
 #endif
 
-#ifdef CONFIG_POWER_SAVING
 #ifdef CONFIG_LPS
        rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, 0, "AP-WOWLAN");
 #endif
-       #endif
 
        DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter));
        return ret;
@@ -3109,6 +3802,14 @@ int rtw_suspend_normal(_adapter *padapter)
        }
 #endif
        rtw_led_control(padapter, LED_CTL_POWER_OFF);
+
+       if ((rtw_hal_check_ips_status(padapter) == _TRUE)
+               || (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off))
+       {
+               DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR #### driver in IPS ####ERROR###!!!\n", __FUNCTION__);       
+               
+       }
+       
 #ifdef CONFIG_CONCURRENT_MODE
        if(rtw_buddy_adapter_up(padapter)){
                rtw_dev_unload(padapter->pbuddy_adapter);
@@ -3136,6 +3837,7 @@ int rtw_suspend_common(_adapter *padapter)
 
        DBG_871X_LEVEL(_drv_always_, " suspend start\n");
        DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
+       
        pdbgpriv->dbg_suspend_cnt++;
        
        pwrpriv->bInSuspend = _TRUE;
@@ -3152,10 +3854,11 @@ int rtw_suspend_common(_adapter *padapter)
        }
 #endif
 
-       if((!padapter->bup) || (padapter->bDriverStopped)||(padapter->bSurpriseRemoved))
-       {
-               DBG_871X("%s bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", __FUNCTION__
-                       ,padapter->bup, padapter->bDriverStopped,padapter->bSurpriseRemoved);
+       if ((!padapter->bup) || RTW_CANNOT_RUN(padapter)) {
+               DBG_871X("%s bup=%d bDriverStopped=%s bSurpriseRemoved = %s\n", __func__
+                       , padapter->bup
+                       , rtw_is_drv_stopped(padapter)?"True":"False"
+                       , rtw_is_surprise_removed(padapter)?"True":"False");
                pdbgpriv->dbg_suspend_error_cnt++;
                goto exit;
        }
@@ -3196,8 +3899,27 @@ int rtw_suspend_common(_adapter *padapter)
 #endif
        ) {
        #ifdef CONFIG_WOWLAN
-               rtw_suspend_wow(padapter);
-       #else
+               if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+                       pwrpriv->wowlan_mode = _TRUE;
+               } else if (pwrpriv->wowlan_pno_enable == _TRUE) {
+                       pwrpriv->wowlan_mode |= pwrpriv->wowlan_pno_enable;
+               }
+
+       #ifdef CONFIG_P2P_WOWLAN
+               if(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE) || P2P_ROLE_DISABLE != padapter->wdinfo.role)
+               {
+                       pwrpriv->wowlan_p2p_mode = _TRUE;
+               }
+               if(_TRUE == pwrpriv->wowlan_p2p_mode)
+                       pwrpriv->wowlan_mode |= pwrpriv->wowlan_p2p_mode;
+       #endif //CONFIG_P2P_WOWLAN
+
+               if (pwrpriv->wowlan_mode == _TRUE)
+                       rtw_suspend_wow(padapter);
+               else
+                       rtw_suspend_normal(padapter);
+               
+       #else //CONFIG_WOWLAN
                rtw_suspend_normal(padapter);
        #endif //CONFIG_WOWLAN
        } else if (check_fwstate(pmlmepriv,WIFI_AP_STATE) == _TRUE
@@ -3223,6 +3945,7 @@ int rtw_suspend_common(_adapter *padapter)
                rtw_suspend_normal(padapter);
        }
 
+
        DBG_871X_LEVEL(_drv_always_, "rtw suspend success in %d ms\n",
                rtw_get_passing_time_ms(start_time));
 
@@ -3237,6 +3960,8 @@ exit:
 int rtw_resume_process_wow(_adapter *padapter)
 {
        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
+       struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
        struct net_device *pnetdev = padapter->pnetdev;
        #ifdef CONFIG_CONCURRENT_MODE
        struct net_device *pbuddy_netdev;       
@@ -3260,16 +3985,27 @@ _func_enter_;
                goto exit;
        }
 
+       if (RTW_CANNOT_RUN(padapter)) {
+               DBG_871X("%s pdapter %p bDriverStopped %s bSurpriseRemoved %s\n"
+                               , __func__, padapter
+                               , rtw_is_drv_stopped(padapter)?"True":"False"
+                               , rtw_is_surprise_removed(padapter)?"True":"False");
+               goto exit;
+       }
+
 #ifdef CONFIG_PNO_SUPPORT
        pwrpriv->pno_in_resume = _TRUE;
-#endif
+#ifdef CONFIG_FWLPS_IN_IPS
+       if(pwrpriv->wowlan_pno_enable)
+               rtw_set_fw_in_ips_mode(padapter, _FALSE);
+#endif //CONFIG_FWLPS_IN_IPS
+#endif//CONFIG_PNO_SUPPORT
 
        if (pwrpriv->wowlan_mode == _TRUE){
-#ifdef CONFIG_POWER_SAVING
 #ifdef CONFIG_LPS
                rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "WOWLAN");
 #endif //CONFIG_LPS
-#endif
+
                pwrpriv->bFwCurrentInPSMode = _FALSE;
 
 #ifdef CONFIG_SDIO_HCI
@@ -3283,8 +4019,7 @@ _func_enter_;
                }
                #endif
 
-               if (padapter->HalFunc.clear_interrupt)
-                       padapter->HalFunc.clear_interrupt(padapter);
+               rtw_hal_clear_interrupt(padapter);
 #endif //CONFIG_SDIO_HCI
 
                //if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) {         
@@ -3296,7 +4031,7 @@ _func_enter_;
 
                //Disable WOW, set H2C command
                poidparam.subcode=WOWLAN_DISABLE;
-               padapter->HalFunc.SetHwRegHandler(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam);
+               rtw_hal_set_hwreg(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam);
 
                #ifdef CONFIG_CONCURRENT_MODE
                rtw_reset_drv_sw(padapter->pbuddy_adapter);
@@ -3308,19 +4043,14 @@ _func_enter_;
                }
 
        
-               padapter->bDriverStopped = _FALSE;
-               DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped);
+               rtw_clr_drv_stopped(padapter);
+               DBG_871X("%s: wowmode resuming, DriverStopped:%s\n", __func__, rtw_is_drv_stopped(padapter)?"True":"False");
                rtw_start_drv_threads(padapter);
 
 #ifdef CONFIG_CONCURRENT_MODE
                if (padapter->pbuddy_adapter)
-               {
-                       padapter->pbuddy_adapter->bDriverStopped = _FALSE;
-                       DBG_871X("%s: wowmode resuming, pbuddy_adapter->DriverStopped:%d\n",
-                               __FUNCTION__, padapter->pbuddy_adapter->bDriverStopped);
                        rtw_start_drv_threads(padapter->pbuddy_adapter);
-               }
-#endif // CONFIG_CONCURRENT_MODE
+#endif /* CONFIG_CONCURRENT_MODE*/
 
                if (padapter->intf_start) {
                        padapter->intf_start(padapter);
@@ -3347,56 +4077,7 @@ _func_enter_;
        }
        else{
 
-               // interface init
-               //if (sdio_init(adapter_to_dvobj(padapter)) != _SUCCESS)
-               if ((padapter->intf_init) &&(padapter->intf_init(adapter_to_dvobj(padapter)) != _SUCCESS))                      
-               {
-                       ret = -1;
-                       RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!!\n", __FUNCTION__));
-                       goto exit;
-               }
-
-               rtw_hal_disable_interrupt(padapter);
-
-               if (padapter->HalFunc.clear_interrupt)
-                       padapter->HalFunc.clear_interrupt(padapter);
-
-               //if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)
-               if ((padapter->intf_alloc_irq)&&(padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS))
-               {
-                       ret = -1;
-                       RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __FUNCTION__));
-                       goto exit;
-               }
-
-               rtw_reset_drv_sw(padapter);
-               #ifdef CONFIG_CONCURRENT_MODE
-               rtw_reset_drv_sw(padapter->pbuddy_adapter);
-               #endif
-               pwrpriv->bkeepfwalive = _FALSE;
-
-               DBG_871X("bkeepfwalive(%x)\n",pwrpriv->bkeepfwalive);
-               
-               if(pm_netdev_close(pnetdev, _TRUE) == 0) {
-                       DBG_871X("netdev_close success\n");
-               }
-
-               if(pm_netdev_open(pnetdev,_TRUE) != 0) {
-                       ret = -1;
-                       pdbgpriv->dbg_resume_error_cnt++;
-                       goto exit;
-               }
-
-               netif_device_attach(pnetdev);   
-               netif_carrier_on(pnetdev);
-               
-               #ifdef CONFIG_CONCURRENT_MODE
-               if(rtw_buddy_adapter_up(padapter)){                     
-                       pbuddy_netdev = padapter->pbuddy_adapter->pnetdev;                                      
-                       netif_device_attach(pbuddy_netdev);
-                       netif_carrier_on(pbuddy_netdev);        
-               }
-               #endif  
+               DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR ### wowlan_mode=%d\n", __FUNCTION__, pwrpriv->wowlan_mode);         
        } 
 
        if( padapter->pid[1]!=0) {
@@ -3412,26 +4093,43 @@ _func_enter_;
                        DBG_871X("%s: disconnect reason: %02x\n", __func__,
                                                pwrpriv->wowlan_wake_reason);
                        rtw_indicate_disconnect(padapter);
-                       rtw_sta_media_status_rpt(padapter, rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)), 0);
+
+                       rtw_sta_media_status_rpt(padapter,
+                               rtw_get_stainfo(&padapter->stapriv,
+                                       get_bssid(&padapter->mlmepriv)), 0);
+
                        rtw_free_assoc_resources(padapter, 1);
+                       pmlmeinfo->state = WIFI_FW_NULL_STATE;
+
                } else {
                        DBG_871X("%s: do roaming\n", __func__);
                        rtw_roaming(padapter, NULL);
                }
        }
 
-       #ifdef CONFIG_RESUME_IN_WORKQUEUE
-       rtw_unlock_suspend();
-       #endif //CONFIG_RESUME_IN_WORKQUEUE
-
+       if (pwrpriv->wowlan_wake_reason == FWDecisionDisconnect) {
+               rtw_lock_ext_suspend_timeout(2000);
+       }
 
        if (pwrpriv->wowlan_wake_reason == Rx_GTK ||
                pwrpriv->wowlan_wake_reason == Rx_DisAssoc ||
-               pwrpriv->wowlan_wake_reason == Rx_DeAuth ||
-               pwrpriv->wowlan_wake_reason == RX_PNOWakeUp) {
+               pwrpriv->wowlan_wake_reason == Rx_DeAuth) {
                rtw_lock_ext_suspend_timeout(8000);
        }
 
+       if (pwrpriv->wowlan_wake_reason == RX_PNOWakeUp) {
+#ifdef CONFIG_IOCTL_CFG80211
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
+                       u8 locally_generated = 1;
+
+                       cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, locally_generated, GFP_ATOMIC);
+#else
+                       cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
+#endif
+#endif /* CONFIG_IOCTL_CFG80211 */
+               rtw_lock_ext_suspend_timeout(10000);
+       }
+
        if (pwrpriv->wowlan_mode == _TRUE) {
                pwrpriv->bips_processing = _FALSE;
                _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000);
@@ -3444,8 +4142,19 @@ _func_enter_;
 
        pwrpriv->wowlan_mode =_FALSE;
 
+       // Power On LED
+#ifdef CONFIG_SW_LED
+       rtw_hal_sw_led_init(padapter);
+       if(pwrpriv->wowlan_wake_reason == Rx_DisAssoc ||
+               pwrpriv->wowlan_wake_reason == Rx_DeAuth ||
+               pwrpriv->wowlan_wake_reason == FWDecisionDisconnect)
+               rtw_led_control(padapter, LED_CTL_NO_LINK);
+       else
+               rtw_led_control(padapter, LED_CTL_LINK);
+#endif
        //clean driver side wake up reason.
        pwrpriv->wowlan_wake_reason = 0;
+
 exit:
        DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter));
 _func_exit_;
@@ -3481,17 +4190,16 @@ _func_enter_;
                goto exit;
        }
 
-#ifdef CONFIG_POWER_SAVING
+
 #ifdef CONFIG_LPS
        rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "AP-WOWLAN");
 #endif //CONFIG_LPS
-#endif
+
        pwrpriv->bFwCurrentInPSMode = _FALSE;
 
        rtw_hal_disable_interrupt(padapter);
 
-       if (padapter->HalFunc.clear_interrupt)
-               padapter->HalFunc.clear_interrupt(padapter);
+       rtw_hal_clear_interrupt(padapter);
                
        //if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) {         
        if((padapter->intf_alloc_irq) && (padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)){
@@ -3502,23 +4210,17 @@ _func_enter_;
 
        //Disable WOW, set H2C command
        poidparam.subcode = WOWLAN_AP_DISABLE;
-       padapter->HalFunc.SetHwRegHandler(padapter,
-               HW_VAR_AP_WOWLAN,(u8 *)&poidparam);
+       rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam);
        pwrpriv->wowlan_ap_mode = _FALSE;
 
-       padapter->bDriverStopped = _FALSE;
-       DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped);
+       rtw_clr_drv_stopped(padapter);
+       DBG_871X("%s: wowmode resuming, DriverStopped:%s\n", __func__, rtw_is_drv_stopped(padapter)?"True":"False");
        rtw_start_drv_threads(padapter);
 
 #ifdef CONFIG_CONCURRENT_MODE
        if (rtw_buddy_adapter_up(padapter))
-       {
-               padapter->pbuddy_adapter->bDriverStopped = _FALSE;
-               DBG_871X("%s: wowmode resuming, pbuddy_adapter->DriverStopped:%d\n",
-                       __FUNCTION__, padapter->pbuddy_adapter->bDriverStopped);
                rtw_start_drv_threads(padapter->pbuddy_adapter);
-       }
-#endif // CONFIG_CONCURRENT_MODE
+#endif /* CONFIG_CONCURRENT_MODE */
 
 #ifdef CONFIG_CONCURRENT_MODE
        if (rtw_buddy_adapter_up(padapter)) {
@@ -3571,7 +4273,7 @@ _func_enter_;
        }       
 
        #ifdef CONFIG_RESUME_IN_WORKQUEUE
-       rtw_unlock_suspend();
+       //rtw_unlock_suspend();
        #endif //CONFIG_RESUME_IN_WORKQUEUE
 
        if (pwrpriv->wowlan_wake_reason == AP_WakeUp)
@@ -3584,6 +4286,12 @@ _func_enter_;
 #endif
        //clean driver side wake up reason.
        pwrpriv->wowlan_wake_reason = 0;
+
+       // Power On LED
+#ifdef CONFIG_SW_LED
+       rtw_hal_sw_led_init(padapter);
+       rtw_led_control(padapter, LED_CTL_LINK);
+#endif
 exit:
        DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter));
 _func_exit_;
@@ -3703,9 +4411,11 @@ _func_enter_;
                }
        }
        #endif
-
+#ifdef CONFIG_SW_LED
+       rtw_hal_sw_led_init(padapter);
+#endif
 #ifdef CONFIG_RESUME_IN_WORKQUEUE
-       rtw_unlock_suspend();
+       //rtw_unlock_suspend();
 #endif //CONFIG_RESUME_IN_WORKQUEUE
        DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter));
 
@@ -3723,6 +4433,9 @@ int rtw_resume_common(_adapter *padapter)
        
        _func_enter_;
 
+       if (pwrpriv->bInSuspend == _FALSE)
+               return 0;
+
        DBG_871X_LEVEL(_drv_always_, "resume start\n");
        DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); 
 
@@ -3732,7 +4445,10 @@ int rtw_resume_common(_adapter *padapter)
 #endif
        ) {
        #ifdef CONFIG_WOWLAN
-               rtw_resume_process_wow(padapter);
+               if (pwrpriv->wowlan_mode == _TRUE)
+                       rtw_resume_process_wow(padapter);
+               else
+                       rtw_resume_process_normal(padapter);
        #else
                rtw_resume_process_normal(padapter);
        #endif
@@ -3777,6 +4493,43 @@ int rtw_resume_common(_adapter *padapter)
        
        return ret;
 }
-#endif
 
+#ifdef CONFIG_GPIO_API
+u8 rtw_get_gpio(struct net_device *netdev, u8 gpio_num)
+{
+       _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev);
+       return rtw_hal_get_gpio(adapter, gpio_num);
+}
+EXPORT_SYMBOL(rtw_get_gpio);
+
+int  rtw_set_gpio_output_value(struct net_device *netdev, u8 gpio_num, bool isHigh)
+{
+       u8 direction = 0;
+       u8 res = -1;
+       _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev);
+       return rtw_hal_set_gpio_output_value(adapter, gpio_num,isHigh);
+}
+EXPORT_SYMBOL(rtw_set_gpio_output_value);
+
+int rtw_config_gpio(struct net_device *netdev, u8 gpio_num, bool isOutput)
+{
+       _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev);        
+       return rtw_hal_config_gpio(adapter,gpio_num,isOutput);  
+}
+EXPORT_SYMBOL(rtw_config_gpio);
+int rtw_register_gpio_interrupt(struct net_device *netdev, int gpio_num, void(*callback)(u8 level))
+{
+       _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev);
+       return rtw_hal_register_gpio_interrupt(adapter,gpio_num,callback);
+}
+EXPORT_SYMBOL(rtw_register_gpio_interrupt);
+
+int rtw_disable_gpio_interrupt(struct net_device *netdev, int gpio_num)
+{
+       _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev);
+       return rtw_hal_disable_gpio_interrupt(adapter,gpio_num);
+}
+EXPORT_SYMBOL(rtw_disable_gpio_interrupt);
+
+#endif //#ifdef CONFIG_GPIO_API