From bedbef8ad3e75a304af6361af235302bcc61d06b Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 14 May 2024 06:39:01 +0000
Subject: [PATCH] 修改内核路径

---
 kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c | 1567 +++++++++++++++++----------------------------------------
 1 files changed, 478 insertions(+), 1,089 deletions(-)

diff --git a/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c b/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c
old mode 100644
new mode 100755
index c03b497..bd23fde
--- a/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iapsta.c
@@ -1,4 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
 
 #ifdef WL_EXT_IAPSTA
 #include <net/rtnetlink.h>
@@ -9,21 +8,10 @@
 #include <dhd_config.h>
 #ifdef WL_CFG80211
 #include <wl_cfg80211.h>
-#include <wl_cfgscan.h>
 #endif /* WL_CFG80211 */
 #ifdef WL_ESCAN
 #include <wl_escan.h>
 #endif /* WL_ESCAN */
-
-#ifdef BTC_WAR
-/* btc_war:
- * -1(don't apply btc)
- *   0(disable btc war): btc_mode=1; txchain=3; rxchain=3
- *   1(enable btc war): txchain=2; rxchain=2; btc_mode=5
- */
-int btc_war = -1;
-module_param(btc_war, int, 0644);
-#endif /* BTC_WAR */
 
 #define IAPSTA_ERROR(name, arg1, args...) \
 	do { \
@@ -69,31 +57,18 @@
 #define CSA_FW_BIT		(1<<0)
 #define CSA_DRV_BIT		(1<<1)
 
-#define WL_DUMP_BUF_LEN (127 * 1024)
-
 #define MAX_AP_LINK_WAIT_TIME   3000
 #define MAX_STA_LINK_WAIT_TIME   15000
 #define STA_LINKDOWN_TIMEOUT	10000
 #define STA_CONNECT_TIMEOUT	10500
-#define STA_CONNECT_FULL_CHAN_TIMEOUT	3000
 #define STA_CONNECT_RETRY_TIMEOUT	600
 #define STA_RECONNECT_RETRY_TIMEOUT	300
-#define STA_DISCONNECT_RECONNECT_TIMEOUT	30000
-#define STA_DISCONNECT_RECONNECT_MAX	3
-#define STA_4WAY_TIMEOUT	1000
-#ifdef EAPOL_RESEND_M4
-#define STA_KEY_INSTALL_INTERVAL	50
-#define STA_KEY_INSTALL_MAX	(STA_4WAY_TIMEOUT/STA_KEY_INSTALL_INTERVAL)
-#else
-#define STA_KEY_INSTALL_INTERVAL	50
-#define STA_KEY_INSTALL_MAX	3
-#endif
 #define STA_EAPOL_TIMEOUT	100
 #define STA_EMPTY_SCAN_MAX	6
-#define AP_RESTART_TIMEOUT	1000
-#define AP_TXBCNFRM_TIMEOUT	10000
+#define AP_RESTART_TIMEOUT	1
+#define AP_TXBCNFRM_TIMEOUT	10
 #ifdef RXF0OVFL_REINIT_WAR
-#define RXF0OVFL_POLLING_TIMEOUT	1000
+#define RXF0OVFL_POLLING_TIMEOUT	1
 #define RXF0OVFL_THRESHOLD	100
 #endif /* RXF0OVFL_REINIT_WAR */
 
@@ -153,12 +128,6 @@
 	ENC_AES,
 	ENC_TKIPAES
 } encmode_t;
-
-typedef enum MAPSTA_MODE {
-	MCHAN_APSTA_NOT_ALLOW = 0,
-	MCHAN_APSTA_SBSC,
-	MCHAN_APSTA_NO_RESTRICT
-} mapsta_mode_t;
 
 #ifdef STA_MGMT
 typedef struct wl_sta_info {
@@ -229,12 +198,6 @@
 	uint conn_state;
 	uint16 prev_channel;
 	uint16 post_channel;
-	struct osl_timespec sta_disc_ts;
-	struct osl_timespec sta_conn_ts;
-	bool ap_recon_sta;
-	wait_queue_head_t ap_recon_sta_event;
-	struct ether_addr ap_disc_sta_bssid;
-	struct osl_timespec ap_disc_sta_ts;
 #ifdef TPUT_MONITOR
 	struct wl_tput_info tput_info;
 #endif /* TPUT_MONITOR */
@@ -256,10 +219,6 @@
 	int eapol_resend_intvl;
 #endif /* EAPOL_DYNAMATIC_RESEND */
 #endif /* EAPOL_RESEND */
-#ifdef KEY_INSTALL_CHECK
-	timer_list_compat_t key_install_timer;
-	int key_install_cnt;
-#endif /* KEY_INSTALL_CHECK */
 	int empty_scan;
 #ifdef RESTART_AP_WAR
 	timer_list_compat_t restart_ap_timer;
@@ -268,21 +227,15 @@
 	timer_list_compat_t reset_ap_timer;
 	uint32 txbcnfrm;
 #endif /* RESET_AP_WAR */
-#if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
-#ifdef WL_EXT_DISCONNECT_RECONNECT
-	struct osl_timespec sta_disc_conn_ts;
-	int sta_disc_recon_cnt;
-#endif /* WL_EXT_DISCONNECT_RECONNECT */
-#endif /* WL_EXT_RECONNECT && WL_CFG80211 */
 } wl_if_info_t;
-
-u8 *g_ioctl_buf = NULL;
 
 typedef struct wl_apsta_params {
 	struct wl_if_info if_info[MAX_IF_NUM];
 #ifdef WLDWDS
 	struct wl_dwds_info dwds_info[MAX_DWDS_IF_NUM];
 #endif /* WLDWDS */
+	struct dhd_pub *dhd;
+	int ioctl_ver;
 	bool init;
 	int rsdb;
 	bool vsdb;
@@ -301,6 +254,12 @@
 #endif /* WLMESH && WL_ESCAN */
 	struct mutex in4way_sync;
 	int sta_btc_mode;
+	struct osl_timespec sta_disc_ts;
+	struct osl_timespec sta_conn_ts;
+	bool ap_recon_sta;
+	wait_queue_head_t ap_recon_sta_event;
+	struct ether_addr ap_disc_sta_bssid;
+	struct osl_timespec ap_disc_sta_ts;
 #ifdef TPUT_MONITOR
 	timer_list_compat_t monitor_timer;
 	int32 tput_sum;
@@ -341,8 +300,7 @@
 	ISAM_RC_AP_RESTART = 4,
 	ISAM_RC_AP_RESET = 5,
 	ISAM_RC_EAPOL_RESEND = 6,
-	ISAM_RC_KEY_INSTALL = 7,
-	ISAM_RC_RXF0OVFL_REINIT = 8
+	ISAM_RC_RXF0OVFL_REINIT = 7
 };
 
 #define wl_get_isam_status(cur_if, stat) \
@@ -357,6 +315,9 @@
 static int wl_ext_enable_iface(struct net_device *dev, char *ifname,
 	int wait_up, bool lock);
 static int wl_ext_disable_iface(struct net_device *dev, char *ifname);
+#if defined(WLMESH) && defined(WL_ESCAN)
+static int wl_mesh_escan_attach(dhd_pub_t *dhd, struct wl_if_info *cur_if);
+#endif /* WLMESH && WL_ESCAN */
 
 static struct wl_if_info *
 wl_get_cur_if(struct net_device *dev)
@@ -643,17 +604,17 @@
 }
 
 static int
-wl_ext_set_emode(struct wl_if_info *cur_if)
+wl_ext_set_emode(struct wl_apsta_params *apsta_params,
+	struct wl_if_info *cur_if)
 {
 	struct net_device *dev = cur_if->dev;
-	struct dhd_pub *dhd = dhd_get_pub(dev);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
+	int wsec=0;
 	struct wl_wsec_key wsec_key;
 	wsec_pmk_t psk;
 	authmode_t amode = cur_if->amode;
 	encmode_t emode = cur_if->emode;
-	int wsec=0;
 	char *key = cur_if->key;
+	struct dhd_pub *dhd = apsta_params->dhd;
 
 	memset(&wsec_key, 0, sizeof(wsec_key));
 	memset(&psk, 0, sizeof(psk));
@@ -749,14 +710,14 @@
 }
 
 static u32
-wl_ext_get_chanspec(struct net_device *dev, struct wl_chan_info *chan_info)
+wl_ext_get_chanspec(struct wl_apsta_params *apsta_params,
+	struct net_device *dev, struct wl_chan_info *chan_info)
 {
-	struct dhd_pub *dhd = dhd_get_pub(dev);
 	u32 chanspec = 0;
 
 	if (wl_ext_associated(dev)) {
 		if (wl_ext_iovar_getint(dev, "chanspec", (s32 *)&chanspec) == BCME_OK) {
-			chanspec = wl_ext_chspec_driver_to_host(dhd, chanspec);
+			chanspec = wl_ext_chspec_driver_to_host(apsta_params->ioctl_ver, chanspec);
 			if (chan_info) {
 				chan_info->band = CHSPEC2WLC_BAND(chanspec);
 				chan_info->chan = wf_chspec_ctlchan(chanspec);
@@ -769,12 +730,13 @@
 }
 
 static uint16
-wl_ext_get_chan(struct net_device *dev, struct wl_chan_info *chan_info)
+wl_ext_get_chan(struct wl_apsta_params *apsta_params,
+	struct net_device *dev, struct wl_chan_info *chan_info)
 {
 	uint16 chan = 0, ctl_chan;
 	u32 chanspec = 0;
 	
-	chanspec = wl_ext_get_chanspec(dev, chan_info);
+	chanspec = wl_ext_get_chanspec(apsta_params, dev, chan_info);
 	if (chanspec) {
 		ctl_chan = wf_chspec_ctlchan(chanspec);
 		chan = (u16)(ctl_chan & 0x00FF);
@@ -783,26 +745,10 @@
 	return chan;
 }
 
-void
-wl_ext_get_chan_str(struct net_device *dev, char *chan_str, int total_len)
-{
-	struct wl_chan_info chan_info;
-	int bytes_written=0;
-	u32 chanspec = 0;
-
-	memset(chan_str, 0, total_len);
-	chanspec = wl_ext_get_chanspec(dev, &chan_info);
-	if (chanspec) {
-		bytes_written += snprintf(chan_str+bytes_written, total_len, "%s-%d %sMHz",
-			WLCBAND2STR(chan_info.band), chan_info.chan,
-			wf_chspec_to_bw_str(chanspec));
-	}
-}
-
 static chanspec_t
-wl_ext_chan_to_chanspec(struct net_device *dev, struct wl_chan_info *chan_info)
+wl_ext_chan_to_chanspec(struct wl_apsta_params *apsta_params,
+	struct net_device *dev, struct wl_chan_info *chan_info)
 {
-	struct dhd_pub *dhd = dhd_get_pub(dev);
 	chanspec_band_t chanspec_band;
 	chanspec_t chspec = 0, fw_chspec = 0;
 	u32 bw = WL_CHANSPEC_BW_20;
@@ -844,7 +790,7 @@
 	chanspec_band = wl_ext_wlcband_to_chanspec_band(chan_info->band);
 	chspec = wf_create_chspec_from_primary(chan_info->chan, bw, chanspec_band);
 	if (wf_chspec_valid(chspec)) {
-		fw_chspec = wl_ext_chspec_host_to_driver(dhd, chspec);
+		fw_chspec = wl_ext_chspec_host_to_driver(apsta_params->ioctl_ver, chspec);
 		if (fw_chspec == INVCHANSPEC) {
 			IAPSTA_ERROR(dev->name, "failed to convert host chanspec to fw chanspec\n");
 			fw_chspec = 0;
@@ -901,88 +847,47 @@
 	return bytes_written;
 }
 
-void
-wl_ext_send_event_msg(struct net_device *dev, int event, int status,
-	int reason)
+static void
+wl_ext_mod_timer(timer_list_compat_t *timer, uint sec, uint msec)
+{
+	uint timeout = sec * 1000 + msec;
+
+	IAPSTA_TRACE("wlan", "timeout=%d\n", timeout);
+
+	if (timer_pending(timer))
+		del_timer_sync(timer);
+
+	if (timeout)
+		mod_timer(timer, jiffies + msecs_to_jiffies(timeout));
+}
+
+static void
+wl_ext_send_event_msg(struct net_device *dev, int event, int status)
 {
 	struct dhd_pub *dhd = dhd_get_pub(dev);
 	struct wl_if_info *cur_if;
 	wl_event_msg_t msg;
 
-	if (dhd && dhd->up) {
-		cur_if = wl_get_cur_if(dev);
-		if (!cur_if)
-			return;
-		bzero(&msg, sizeof(wl_event_msg_t));
-		msg.ifidx = dhd_net2idx(dhd->info, dev);
-		msg.event_type = hton32(event);
-		msg.status = hton32(status);
-		msg.reason = hton32(reason);
-		memcpy(&msg.addr, &cur_if->bssid, ETHER_ADDR_LEN);
+	cur_if = wl_get_cur_if(dev);
+	if (!cur_if)
+		return;
+
+	bzero(&msg, sizeof(wl_event_msg_t));
+
+	msg.ifidx = dhd_net2idx(dhd->info, dev);
+	msg.event_type = hton32(event);
+	msg.status = hton32(status);
+	memcpy(&msg.addr, &cur_if->bssid, ETHER_ADDR_LEN);
+
 #ifdef WL_EVENT
-		wl_ext_event_send(dhd->event_params, &msg, NULL);
-#endif /* WL_EVENT */
+	wl_ext_event_send(dhd->event_params, &msg, NULL);
+#endif
 #ifdef WL_CFG80211
+	if (dhd->up) {
 		wl_cfg80211_event(dev, &msg, NULL);
-#endif /* WL_CFG80211 */
 	}
+#endif /* defined(WL_CFG80211) */
 }
-
-#ifdef BTC_WAR
-bool
-wl_ext_iapsta_if_2g_enabled(struct net_device *net)
-{
-	struct dhd_pub *dhd = dhd_get_pub(net);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
-	struct wl_if_info *tmp_if;
-	struct wl_chan_info chan_info;
-	bool enabled = FALSE;
-	uint16 cur_chan;
-	int i;
-
-	for (i=0; i<MAX_IF_NUM; i++) {
-		tmp_if = &apsta_params->if_info[i];
-		if (tmp_if && wl_get_isam_status(tmp_if, IF_READY)) {
-			cur_chan = wl_ext_get_chan(tmp_if->dev, &chan_info);
-			if (cur_chan && chan_info.band == WLC_BAND_2G) {
-				enabled = TRUE;
-				break;
-			}
-		}
-	}
-
-	return enabled;
-}
-
-void
-wl_ext_btc_config(struct net_device *dev, bool enable)
-{
-	struct dhd_pub *dhd = dhd_get_pub(dev);
-	bool enab = FALSE;
-
-	if (dhd->conf->chip == BCM4354_CHIP_ID || dhd->conf->chip == BCM4356_CHIP_ID ||
-			dhd->conf->chip == BCM43752_CHIP_ID) {
-		IAPSTA_INFO(dev->name, "btc_war=%d, enable=%d\n", btc_war, enable);
-		if (btc_war >= 0) {
-			if (enable && btc_war > 0) {
-				if (wl_ext_iapsta_if_2g_enabled(dev))
-					enab = TRUE;
-			}
-			if (enab) {
-				IAPSTA_INFO(dev->name, "enable\n");
-				wl_ext_iovar_setint(dev, "txchain", 2);
-				wl_ext_iovar_setint(dev, "rxchain", 2);
-				wl_ext_iovar_setint(dev, "btc_mode", 5);
-			} else {
-				IAPSTA_INFO(dev->name, "disable\n");
-				wl_ext_iovar_setint(dev, "btc_mode", 1);
-				wl_ext_iovar_setint(dev, "txchain", 3);
-				wl_ext_iovar_setint(dev, "rxchain", 3);
-			}
-		}
-	}
-}
-#endif /* BTC_WAR */
 
 static void
 wl_ext_connect_timeout(unsigned long data)
@@ -1003,7 +908,7 @@
 	cur_if->assoc_info.reassoc = 0;
 #endif /* WL_EXT_RECONNECT && WL_CFG80211 */
 	IAPSTA_ERROR(dev->name, "timer expired\n");
-	wl_ext_send_event_msg(dev, WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WLC_E_STATUS_SUCCESS);
+	wl_ext_send_event_msg(dev, WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS);
 }
 
 #if defined(WL_CFG80211) || (defined(WLMESH) && defined(WL_ESCAN))
@@ -1131,7 +1036,7 @@
 }
 
 #ifdef WL_ESCAN
-#define WL_MESH_DELAY_SCAN_TMO	3000
+#define WL_MESH_DELAY_SCAN_TMO	3
 static void
 wl_mesh_timer(unsigned long data)
 {
@@ -1223,10 +1128,9 @@
 }
 
 static int
-wl_mesh_clear_mesh_info(struct wl_if_info *mesh_if, bool scan)
+wl_mesh_clear_mesh_info(struct wl_apsta_params *apsta_params,
+	struct wl_if_info *mesh_if, bool scan)
 {
-	struct dhd_pub *dhd = dhd_get_pub(mesh_if->dev);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
 	struct wl_mesh_params *mesh_info = &apsta_params->mesh_info;
 	uchar mesh_oui[]={0x00, 0x22, 0xf4};
 	int ret;
@@ -1236,9 +1140,9 @@
 	ret = wl_mesh_clear_vndr_ie(mesh_if->dev, mesh_oui);
 	memset(mesh_info, 0, sizeof(struct wl_mesh_params));
 	if (scan) {
-		mesh_info->scan_channel = wl_ext_get_chan(mesh_if->dev,
+		mesh_info->scan_channel = wl_ext_get_chan(apsta_params, mesh_if->dev,
 			&mesh_if->chan_info);
-		wl_timer_mod(dhd, &mesh_if->delay_scan, 100);
+		wl_ext_mod_timer(&mesh_if->delay_scan, 0, 100);
 	}
 
 	return ret;
@@ -1317,7 +1221,8 @@
 	if (sta_if) {
 		wldev_ioctl(mesh_if->dev, WLC_GET_BSSID, &mesh_info->master_bssid,
 			ETHER_ADDR_LEN, 0);
-		mesh_info->master_channel = wl_ext_get_chan(mesh_if->dev, &mesh_if->chan_info);
+		mesh_info->master_channel = wl_ext_get_chan(apsta_params, mesh_if->dev,
+			&mesh_if->chan_info);
 		mesh_info->hop_cnt = 0;
 		memset(mesh_info->peer_bssid, 0, MAX_HOP_LIST*ETHER_ADDR_LEN);
 		if (!wl_mesh_update_vndr_ie(apsta_params, mesh_if))
@@ -1393,7 +1298,8 @@
 		wl_ext_get_sec(mesh_if->dev, mesh_if->ifmode, sec, sizeof(sec), FALSE);
 		if (strnicmp(sec, "sae/sae", strlen("sae/sae")) == 0)
 			sae = TRUE;
-		cur_chan = wl_ext_get_chan(mesh_if->dev, &mesh_if->chan_info);
+		cur_chan = wl_ext_get_chan(apsta_params, mesh_if->dev,
+			&mesh_if->chan_info);
 		bss_found = wl_escan_mesh_peer(mesh_if->dev, mesh_if->escan, &cur_ssid, cur_chan,
 			sae, &peer_mesh_info);
 
@@ -1414,105 +1320,67 @@
 }
 
 static void
-wl_mesh_event_handler(struct wl_if_info *cur_if,
-	const wl_event_msg_t *e, void *data)
+wl_mesh_event_handler(struct wl_apsta_params *apsta_params,
+	struct wl_if_info *mesh_if, const wl_event_msg_t *e, void *data)
 {
-	struct dhd_pub *dhd = dhd_get_pub(cur_if->dev);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
 	struct wl_mesh_params *mesh_info = &apsta_params->mesh_info;
 	uint32 event_type = ntoh32(e->event_type);
 	uint32 status = ntoh32(e->status);
 	uint32 reason = ntoh32(e->reason);
-	uint16 flags =  ntoh16(e->flags);
-	struct wl_if_info *mesh_if = NULL, *tmp_if = NULL;
-	int ret, i;
+	int ret;
 
-	if (cur_if->ifmode == IMESH_MODE)
-		mesh_if = cur_if;
-	else {
-		for (i=0; i<MAX_IF_NUM; i++) {
-			tmp_if = &apsta_params->if_info[i];
-			if (tmp_if->dev && tmp_if->ifmode == IMESH_MODE) {
-				mesh_if = tmp_if;
-				break;
-			}
+	if (wl_get_isam_status(mesh_if, AP_CREATED) &&
+			((event_type == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) ||
+			(event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
+			reason == WLC_E_REASON_INITIAL_ASSOC))) {
+		if (!wl_mesh_update_master_info(apsta_params, mesh_if)) {
+			mesh_info->scan_channel = wl_ext_get_chan(apsta_params, &mesh_if->dev,
+				mesh_if->chan_info);
+			wl_ext_mod_timer(&mesh_if->delay_scan, WL_MESH_DELAY_SCAN_TMO, 0);
 		}
 	}
-
-	if (cur_if->ifmode == ISTA_MODE || cur_if->ifmode == IGC_MODE) {
-		if (event_type == WLC_E_LINK) {
-			if (!(flags & WLC_EVENT_MSG_LINK)) {
-				if (mesh_if && apsta_params->macs)
-					wl_mesh_clear_mesh_info(mesh_if, TRUE);
-			} else {
-				if (mesh_if && apsta_params->macs)
-					wl_mesh_update_master_info(apsta_params, mesh_if);
+	else if ((event_type == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS) ||
+			(event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
+			reason == WLC_E_REASON_DEAUTH)) {
+		wl_mesh_clear_mesh_info(apsta_params, mesh_if, FALSE);
+	}
+	else if (wl_get_isam_status(mesh_if, AP_CREATED) &&
+			(event_type == WLC_E_ASSOC_IND || event_type == WLC_E_REASSOC_IND) &&
+			reason == DOT11_SC_SUCCESS) {
+		mesh_info->scan_channel = wl_ext_get_chan(apsta_params, mesh_if->dev,
+			&mesh_if->chan_info);
+		wl_ext_mod_timer(&mesh_if->delay_scan, 0, 100);
+	}
+	else if (event_type == WLC_E_DISASSOC_IND || event_type == WLC_E_DEAUTH_IND ||
+			(event_type == WLC_E_DEAUTH && reason != DOT11_RC_RESERVED)) {
+		if (!memcmp(&mesh_info->peer_bssid, &e->addr, ETHER_ADDR_LEN))
+			wl_mesh_clear_mesh_info(apsta_params, mesh_if, TRUE);
+	}
+	else if (wl_get_isam_status(mesh_if, AP_CREATED) &&
+			event_type == WLC_E_RESERVED && reason == ISAM_RC_MESH_ACS) {
+		if (!wl_mesh_update_master_info(apsta_params, mesh_if)) {
+			wl_scan_info_t scan_info;
+			memset(&scan_info, 0, sizeof(wl_scan_info_t));
+			wl_ext_ioctl(mesh_if->dev, WLC_GET_SSID, &scan_info.ssid, sizeof(wlc_ssid_t), 0);
+			if (mesh_info->scan_channel) {
+				scan_info.channels.count = 1;
+				scan_info.channels.channel[0] = mesh_info->scan_channel;
 			}
-		}
-		else if (event_type == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) {
-			if (mesh_if && apsta_params->macs)
-				wl_mesh_clear_mesh_info(mesh_if, TRUE);
-		}
-		else if (event_type == WLC_E_DEAUTH || event_type == WLC_E_DEAUTH_IND ||
-				event_type == WLC_E_DISASSOC || event_type == WLC_E_DISASSOC_IND) {
-			if (mesh_if && apsta_params->macs)
-				wl_mesh_clear_mesh_info(mesh_if, TRUE);
+			ret = wl_escan_set_scan(mesh_if->dev, &scan_info);
+			if (ret)
+				wl_ext_mod_timer(&mesh_if->delay_scan, WL_MESH_DELAY_SCAN_TMO, 0);
 		}
 	}
-	else if (cur_if->ifmode == IMESH_MODE && apsta_params->macs) {
-		if (wl_get_isam_status(mesh_if, AP_CREATED) &&
-				((event_type == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) ||
-				(event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
-				reason == WLC_E_REASON_INITIAL_ASSOC))) {
-			if (!wl_mesh_update_master_info(apsta_params, mesh_if)) {
-				mesh_info->scan_channel = wl_ext_get_chan(&mesh_if->dev,
-					mesh_if->chan_info);
-				wl_timer_mod(dhd, &mesh_if->delay_scan, WL_MESH_DELAY_SCAN_TMO);
-			}
-		}
-		else if ((event_type == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS) ||
-				(event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
-				reason == WLC_E_REASON_DEAUTH)) {
-			wl_mesh_clear_mesh_info(mesh_if, FALSE);
-		}
-		else if (wl_get_isam_status(mesh_if, AP_CREATED) &&
-				(event_type == WLC_E_ASSOC_IND || event_type == WLC_E_REASSOC_IND) &&
-				reason == DOT11_SC_SUCCESS) {
-			mesh_info->scan_channel = wl_ext_get_chan(mesh_if->dev,
-				&mesh_if->chan_info);
-			wl_timer_mod(dhd, &mesh_if->delay_scan, 100);
-		}
-		else if (event_type == WLC_E_DISASSOC_IND || event_type == WLC_E_DEAUTH_IND ||
-				(event_type == WLC_E_DEAUTH && reason != DOT11_RC_RESERVED)) {
-			if (!memcmp(&mesh_info->peer_bssid, &e->addr, ETHER_ADDR_LEN))
-				wl_mesh_clear_mesh_info(mesh_if, TRUE);
-		}
-		else if (wl_get_isam_status(mesh_if, AP_CREATED) &&
-				event_type == WLC_E_RESERVED && reason == ISAM_RC_MESH_ACS) {
-			if (!wl_mesh_update_master_info(apsta_params, mesh_if)) {
-				wl_scan_info_t scan_info;
-				memset(&scan_info, 0, sizeof(wl_scan_info_t));
-				wl_ext_ioctl(mesh_if->dev, WLC_GET_SSID, &scan_info.ssid, sizeof(wlc_ssid_t), 0);
-				if (mesh_info->scan_channel) {
-					scan_info.channels.count = 1;
-					scan_info.channels.channel[0] = mesh_info->scan_channel;
-				}
-				ret = wl_escan_set_scan(mesh_if->dev, &scan_info);
-				if (ret)
-					wl_timer_mod(dhd, &mesh_if->delay_scan, WL_MESH_DELAY_SCAN_TMO);
-			}
-		}
-		else if (wl_get_isam_status(mesh_if, AP_CREATED) &&
-				((event_type == WLC_E_ESCAN_RESULT && status == WLC_E_STATUS_SUCCESS) ||
-				(event_type == WLC_E_ESCAN_RESULT &&
-				(status == WLC_E_STATUS_ABORT || status == WLC_E_STATUS_NEWSCAN ||
-				status == WLC_E_STATUS_11HQUIET || status == WLC_E_STATUS_CS_ABORT ||
-				status == WLC_E_STATUS_NEWASSOC || status == WLC_E_STATUS_TIMEOUT)))) {
-			if (!wl_mesh_update_master_info(apsta_params, mesh_if)) {
-				if (!wl_mesh_update_mesh_info(apsta_params, mesh_if)) {
-					mesh_info->scan_channel = 0;
-					wl_timer_mod(dhd, &mesh_if->delay_scan, WL_MESH_DELAY_SCAN_TMO);
-				}
+	else if (wl_get_isam_status(mesh_if, AP_CREATED) &&
+			((event_type == WLC_E_ESCAN_RESULT && status == WLC_E_STATUS_SUCCESS) ||
+			(event_type == WLC_E_ESCAN_RESULT &&
+			(status == WLC_E_STATUS_ABORT || status == WLC_E_STATUS_NEWSCAN ||
+			status == WLC_E_STATUS_11HQUIET || status == WLC_E_STATUS_CS_ABORT ||
+			status == WLC_E_STATUS_NEWASSOC || status == WLC_E_STATUS_TIMEOUT)))) {
+		if (!wl_mesh_update_master_info(apsta_params, mesh_if)) {
+			if (!wl_mesh_update_mesh_info(apsta_params, mesh_if)) {
+				mesh_info->scan_channel = 0;
+				wl_ext_mod_timer(&mesh_if->delay_scan, WL_MESH_DELAY_SCAN_TMO, 0);
 			}
 		}
 	}
@@ -1522,7 +1390,9 @@
 wl_mesh_escan_detach(dhd_pub_t *dhd, struct wl_if_info *mesh_if)
 {
 	IAPSTA_TRACE(mesh_if->dev->name, "Enter\n");
-	wl_timer_deregister(mesh_if->dev, &mesh_if->delay_scan);
+
+	del_timer_sync(&mesh_if->delay_scan);
+
 	if (mesh_if->escan) {
 		mesh_if->escan = NULL;
 	}
@@ -1534,7 +1404,7 @@
 	IAPSTA_TRACE(mesh_if->dev->name, "Enter\n");
 
 	mesh_if->escan = dhd->escan;
-	wl_timer_register(mesh_if->dev, &mesh_if->delay_scan, wl_mesh_timer);
+	init_timer_compat(&mesh_if->delay_scan, wl_mesh_timer, mesh_if->dev);
 
 	return 0;
 }
@@ -1709,10 +1579,6 @@
 		WL_MSG(cur_if->ifname, "[%c] skip DFS channel %d\n",
 			cur_if->prefix, chan_info->chan);
 		return 0;
-	} else if (wl_ext_passive_chan(cur_if->dev, chan_info)) {
-		WL_MSG(cur_if->ifname, "[%c] skip PASSIVE channel %d\n",
-			cur_if->prefix, chan_info->chan);
-		return 0;
 	} else if (!chan_info->chan) {
 		WL_MSG(cur_if->ifname, "[%c] no valid channel\n", cur_if->prefix);
 		return 0;
@@ -1747,7 +1613,7 @@
 	}
 
 	wl_ext_ioctl(cur_if->dev, WLC_GET_SSID, &ssid, sizeof(ssid), 0);
-	chanspec = wl_ext_get_chanspec(cur_if->dev, chan_info);
+	chanspec = wl_ext_get_chanspec(apsta_params, cur_if->dev, chan_info);
 	WL_MSG(cur_if->ifname, "[%c] enabled with SSID: \"%s\" on channel %s-%d(0x%x)\n",
 		cur_if->prefix, ssid.SSID, CHSPEC2BANDSTR(chanspec),
 		chan_info->chan, chanspec);
@@ -1797,7 +1663,7 @@
 		if (cur_if != tmp_if && wl_get_isam_status(tmp_if, IF_READY) &&
 				tmp_if->prio > max_prio) {
 			memset(&chan_info, 0, sizeof(struct wl_chan_info));
-			wl_ext_get_chan(tmp_if->dev, &chan_info);
+			wl_ext_get_chan(apsta_params, tmp_if->dev, &chan_info);
 			if (wl_ext_dfs_chan(&chan_info) && nodfs)
 				continue;
 			if (chan_info.chan && (cur_if->chan_info.band == chan_info.band)) {
@@ -1824,7 +1690,7 @@
 		return 0;
 
 	memset(&chan_info, 0, sizeof(struct wl_chan_info));
-	target_chan = wl_ext_get_chan(target_if->dev, &chan_info);
+	target_chan = wl_ext_get_chan(apsta_params, target_if->dev, &chan_info);
 	if (target_chan) {
 		target_band = chan_info.band;
 		IAPSTA_INFO(cur_if->ifname, "cur_chan=%s-%d, target_chan=%s-%d\n",
@@ -1852,13 +1718,13 @@
 
 	if (apsta_params->rsdb) {
 		memset(&cur_chan_info, 0, sizeof(struct wl_chan_info));
-		wl_ext_get_chan(cur_if->dev, &cur_chan_info);
+		wl_ext_get_chan(apsta_params, cur_if->dev, &cur_chan_info);
 		for (i=0; i<MAX_IF_NUM; i++) {
 			tmp_if = &apsta_params->if_info[i];
 			if (tmp_if != cur_if && wl_get_isam_status(tmp_if, IF_READY) &&
 					tmp_if->prio > cur_if->prio) {
 				memset(&tmp_chan_info, 0, sizeof(struct wl_chan_info));
-				wl_ext_get_chan(tmp_if->dev, &tmp_chan_info);
+				wl_ext_get_chan(apsta_params, tmp_if->dev, &tmp_chan_info);
 				if (!tmp_chan_info.chan)
 					continue;
 				if (wl_ext_rsdb_band(cur_chan_info.band, tmp_chan_info.band) &&
@@ -1891,7 +1757,8 @@
 			memset(&csa_arg, 0, sizeof(csa_arg));
 			csa_arg.mode = 1;
 			csa_arg.count = 3;
-			csa_arg.chspec = wl_ext_chan_to_chanspec(cur_if->dev, &cur_if->chan_info);
+			csa_arg.chspec = wl_ext_chan_to_chanspec(apsta_params, cur_if->dev,
+				&cur_if->chan_info);
 			core_conflict = wl_ext_rsdb_core_conflict(apsta_params, cur_if);
 			if (core_conflict) {
 				WL_MSG(cur_if->ifname, "[%c] Skip CSA due to rsdb core conflict\n",
@@ -1940,7 +1807,6 @@
 			if (!auto_chan) {
 				auto_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT,
 					cur_chan_info->band);
-				auto_chan = wf_chspec_ctlchan(auto_chan);
 			}
 			if (auto_chan)
 				cur_chan_info->chan = auto_chan;
@@ -1962,7 +1828,6 @@
 			if (!auto_chan) {
 				auto_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT,
 					cur_chan_info->band);
-				auto_chan = wf_chspec_ctlchan(auto_chan);
 			}
 			if (auto_chan) {
 				cur_chan_info->chan = auto_chan;
@@ -1976,7 +1841,6 @@
 			} else {
 				auto_chan = wl_ext_autochannel(cur_if->dev, ACS_FW_BIT|ACS_DRV_BIT,
 					cur_chan_info->band);
-				auto_chan = wf_chspec_ctlchan(auto_chan);
 				if (auto_chan) {
 					cur_chan_info->chan = auto_chan;
 				}
@@ -2015,7 +1879,6 @@
 			if (!auto_chan) {
 				auto_chan = wl_ext_autochannel(tgt_if->dev, ACS_FW_BIT|ACS_DRV_BIT,
 					tgt_chan_info->band);
-				auto_chan = wf_chspec_ctlchan(auto_chan);
 			}
 			if (auto_chan) {
 				tgt_chan_info->chan = auto_chan;
@@ -2028,7 +1891,6 @@
 				if (!auto_chan) {
 					auto_chan = wl_ext_autochannel(tgt_if->dev, ACS_FW_BIT|ACS_DRV_BIT,
 						tgt_chan_info->band);
-					auto_chan = wf_chspec_ctlchan(auto_chan);
 				}
 			} else {
 				tgt_chan_info->chan = 0;
@@ -2076,8 +1938,8 @@
 	if (target_if) {
 		memset(&cur_chan_info, 0, sizeof(struct wl_chan_info));
 		memset(&tgt_chan_info, 0, sizeof(struct wl_chan_info));
-		wl_ext_get_chan(cur_if->dev, &cur_chan_info);
-		wl_ext_get_chan(target_if->dev, &tgt_chan_info);
+		wl_ext_get_chan(apsta_params, cur_if->dev, &cur_chan_info);
+		wl_ext_get_chan(apsta_params, target_if->dev, &tgt_chan_info);
 		if (apsta_params->rsdb && cur_chan_info.chan &&
 				wl_ext_rsdb_band(cur_chan_info.band, tgt_chan_info.band)) {
 			WL_MSG(cur_if->ifname, "[%c] keep on current channel %s-%d\n",
@@ -2239,50 +2101,6 @@
 	return connecting;
 }
 
-bool
-wl_ext_sta_handshaking(struct net_device *dev)
-{
-	struct wl_if_info *cur_if = NULL;
-	bool connecting = FALSE;
-	int state;
-
-	cur_if = wl_get_cur_if(dev);
-	if (!cur_if)
-		return FALSE;
-
-	if (cur_if->ifmode != ISTA_MODE && cur_if->ifmode != IGC_MODE)
-		return FALSE;
-
-	state = cur_if->conn_state;
-	if (state >= CONN_STATE_4WAY_M1 && state < CONN_STATE_CONNECTED) {
-		connecting = TRUE;
-		IAPSTA_TRACE(dev->name, "conn_state %d\n", state);
-	}
-
-	return connecting;
-}
-
-#ifdef DHD_LOSSLESS_ROAMING
-int
-wl_ext_any_sta_handshaking(struct dhd_pub *dhd)
-{
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
-	struct wl_if_info *cur_if;
-	int state = 0, i;
-
-	for (i=0; i<MAX_IF_NUM; i++) {
-		cur_if = &apsta_params->if_info[i];
-		if (cur_if->dev && cur_if->ifmode == ISTA_MODE) {
-			state = cur_if->conn_state;
-			if (state >= CONN_STATE_4WAY_M1 && state < CONN_STATE_CONNECTED) {
-				return state;
-			}
-		}
-	}
-	return 0;
-}
-#endif /* DHD_LOSSLESS_ROAMING */
-
 #ifdef PROPTX_MAXCOUNT
 int
 wl_ext_get_wlfc_maxcount(struct dhd_pub *dhd, int ifidx)
@@ -2325,7 +2143,7 @@
 		tmp_if = &apsta_params->if_info[i];
 		if (tmp_if->dev) {
 			memset(&chan_info, 0, sizeof(struct wl_chan_info));
-			wl_ext_get_chan(tmp_if->dev, &chan_info);
+			wl_ext_get_chan(apsta_params, tmp_if->dev, &chan_info);
 			if (chan_info.band == WLC_BAND_5G || chan_info.band == WLC_BAND_6G) {
 				tmp_if->transit_maxcount = dhd->conf->proptx_maxcnt_5g;
 				ret = dhd_wlfc_update_maxcount(dhd, tmp_if->ifidx,
@@ -2341,7 +2159,7 @@
 	for (i=0; i<MAX_IF_NUM; i++) {
 		tmp_if = &apsta_params->if_info[i];
 		if (tmp_if->dev) {
-			wl_ext_get_chan(tmp_if->dev, &chan_info);
+			wl_ext_get_chan(apsta_params, tmp_if->dev, &chan_info);
 			if ((chan_info.chan == 0) || (chan_info.band == WLC_BAND_2G)) {
 				if (chan_info.chan == 0) {
 					tmp_if->transit_maxcount = WL_TXSTATUS_FREERUNCTR_MASK;
@@ -2374,7 +2192,7 @@
 		if (!cur_if->dev || !wl_ext_master_if(cur_if))
 			continue;
 		memset(&chan_info, 0, sizeof(struct wl_chan_info));
-		wl_ext_get_chan(cur_if->dev, &chan_info);
+		wl_ext_get_chan(apsta_params, cur_if->dev, &chan_info);
 		if (chan_info.chan && wl_ext_dfs_chan(&chan_info)) {
 			return cur_if;
 		}
@@ -2398,7 +2216,7 @@
 		if (!cur_if->dev || !wl_ext_master_if(cur_if))
 			continue;
 		memset(&chan_info, 0, sizeof(struct wl_chan_info));
-		wl_ext_get_chan(cur_if->dev, &chan_info);
+		wl_ext_get_chan(apsta_params, cur_if->dev, &chan_info);
 		if (chan_info.chan) {
 			cur_if->prev_channel = chan_info.chan;
 			cur_if->post_channel = post_channel;
@@ -2421,8 +2239,6 @@
 				cur_if->chan_info.chan = cur_if->post_channel;
 			else
 				cur_if->chan_info.chan = cur_if->prev_channel;
-			if (wl_ext_associated(cur_if->dev))
-				wl_ext_if_down(apsta_params, cur_if);
 			wl_ext_if_up(apsta_params, cur_if, TRUE, 0);
 			cur_if->prev_channel = 0;
 			cur_if->post_channel = 0;
@@ -2469,7 +2285,7 @@
 		tmp_if = &apsta_params->if_info[i];
 		if (tmp_if && tmp_if->ifmode == ifmode &&
 				wl_get_isam_status(tmp_if, IF_READY)) {
-			if (wl_ext_get_chan(tmp_if->dev, &tmp_if->chan_info) == channel) {
+			if (wl_ext_get_chan(apsta_params, tmp_if->dev, &tmp_if->chan_info) == channel) {
 			    WL_MSG(tmp_if->ifname, "re-enable channel %d\n", channel);
 				if (ifmode == IAP_MODE) {
 					wl_ext_if_down(apsta_params, tmp_if);
@@ -2500,7 +2316,6 @@
 		if (wl_ext_master_if(cur_if) && apsta_params->acs) {
 			chan_info->chan = wl_ext_autochannel(cur_if->dev, apsta_params->acs,
 				chan_info->band);
-			chan_info->chan = wf_chspec_ctlchan(chan_info->chan);
 		}
 		chan_info->chan = wl_ext_move_cur_channel(apsta_params, cur_if);
 		if (chan_info->chan) {
@@ -2518,7 +2333,7 @@
 			}
 		}
 		if (cur_if->ifmode == ISTA_MODE) {
-			if (conf->war & SET_CHAN_INCONN && chan_info->chan) {
+			if (conf->war & SET_CHAN_INCONN) {
 				chanspec_t fw_chspec;
 			    IAPSTA_INFO(dev->name, "set channel %d\n", chan_info->chan);
 			    wl_ext_set_chanspec(cur_if->dev, chan_info, &fw_chspec);
@@ -2576,9 +2391,6 @@
 			cur_if->prio = PRIO_STA;
 			cur_if->vsdb = TRUE;
 			cur_if->prefix = 'S';
-#ifdef WL_STATIC_IF
-			dhd_conf_preinit_ioctls_sta(dhd, ifidx);
-#endif /* WL_STATIC_IF */
 		} else if (wl_iftype == WL_IF_TYPE_AP && cur_if->ifmode != IMESH_MODE) {
 			cur_if->ifmode = IAP_MODE;
 			cur_if->prio = PRIO_AP;
@@ -2683,84 +2495,7 @@
 		return;
 	}
 	IAPSTA_ERROR(dev->name, "timer expired\n");
-	wl_ext_send_event_msg(dev, WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WLC_E_STATUS_SUCCESS);
-}
-
-#ifdef WL_EXT_DISCONNECT_RECONNECT
-static bool
-wl_ext_disc_recon_retry(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if)
-{
-	int sta_disc_recon_cnt = cur_if->sta_disc_recon_cnt;
-	struct osl_timespec *sta_disc_conn_ts = &cur_if->sta_disc_conn_ts;
-	struct osl_timespec cur_ts;
-	uint32 diff_ms = 0;
-	bool retry = FALSE;
-
-	if (sta_disc_recon_cnt == 0)
-		osl_do_gettimeofday(sta_disc_conn_ts);
-
-	osl_do_gettimeofday(&cur_ts);
-	diff_ms = osl_do_gettimediff(&cur_ts, sta_disc_conn_ts)/1000;
-
-	IAPSTA_INFO(cur_if->ifname, "sta_disc_recon_cnt=%d, diff_ms = %dms\n",
-		sta_disc_recon_cnt, diff_ms);
-	if (sta_disc_recon_cnt >= STA_DISCONNECT_RECONNECT_MAX) {
-		if (diff_ms >= STA_DISCONNECT_RECONNECT_TIMEOUT) {
-			osl_do_gettimeofday(sta_disc_conn_ts);
-			cur_if->sta_disc_recon_cnt = 0;
-			retry = TRUE;
-		} else {
-			retry = FALSE;
-		}
-	} else {
-		retry = TRUE;
-	}
-
-	if (retry)
-		cur_if->sta_disc_recon_cnt++;
-
-	return retry;
-}
-#endif /* WL_EXT_DISCONNECT_RECONNECT */
-
-static void
-wl_ext_update_assoc_info(struct net_device *dev, bool reassoc)
-{
-#ifndef WL_REASSOC_BCAST
-	dhd_pub_t *dhd = dhd_get_pub(dev);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
-	struct wl_chan_info chan_info;
-#endif
-	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
-	wlcfg_assoc_info_t *assoc_info;
-	struct wl_if_info *cur_if;
-
-	cur_if = wl_get_cur_if(dev);
-	if (cur_if) {
-		assoc_info = &cur_if->assoc_info;
-		assoc_info->reassoc = reassoc;
-		assoc_info->bssid_hint = false;
-#ifdef WL_REASSOC_BCAST
-		assoc_info->chan_cnt = 0;
-		assoc_info->chanspecs[0] = 0;
-		memcpy(&assoc_info->bssid, &ether_bcast, ETHER_ADDR_LEN);
-#else
-		assoc_info->chanspecs[0] = wl_ext_get_chanspec(dev, &chan_info);
-		if (assoc_info->chanspecs[0] && reassoc) {
-			assoc_info->chan_cnt = 1;
-			wldev_ioctl(dev, WLC_GET_BSSID, &cur_if->bssid, ETHER_ADDR_LEN, 0);
-			memcpy(&assoc_info->bssid, &cur_if->bssid, ETHER_ADDR_LEN);
-		} else {
-			assoc_info->chan_cnt = 0;
-			memcpy(&assoc_info->bssid, &ether_bcast, ETHER_ADDR_LEN);
-		}
-#endif /* WL_REASSOC_BCAST */
-		if (!ETHER_ISBCAST(assoc_info->bssid))
-			assoc_info->targeted_join = true;
-		else
-			assoc_info->targeted_join = false;
-		wl_get_assoc_channels(cfg, dev, assoc_info);
-	}
+	wl_ext_send_event_msg(dev, WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS);
 }
 
 static int
@@ -2770,122 +2505,45 @@
 	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
 	struct wl_if_info *cur_if;
 	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
-	struct osl_timespec cur_ts, *sta_conn_ts;
-	wlcfg_assoc_info_t *assoc_info;
+	struct osl_timespec cur_ts, *sta_conn_ts = &apsta_params->sta_conn_ts;
 	uint32 diff_ms = 0;
 	int max_wait_time = 0, ret = 0;
-	bool connecting, handshaking, associated;
-	uint32 etype = ntoh32(e->event_type);
-	uint32 status = ntoh32(e->status);
-
-	if (wl_get_drv_status(cfg, DISCONNECTING, dev)) {
-		WL_MSG(dev->name, "skip connect retry due to disconnecting\n");
-		return BCME_BADADDR;
-	}
+	bool connecting = FALSE;
 
 	cur_if = wl_get_cur_if(dev);
 	if (!cur_if)
 		return ret;
-	sta_conn_ts = &cur_if->sta_conn_ts;
-	connecting = wl_ext_sta_connecting(dev);
-	handshaking = wl_ext_sta_handshaking(dev);
 
 	mutex_unlock(&apsta_params->in4way_sync);
 	mutex_lock(&cfg->connect_sync);
+	connecting = wl_ext_sta_connecting(dev);
 
 	osl_do_gettimeofday(&cur_ts);
 	diff_ms = osl_do_gettimediff(&cur_ts, sta_conn_ts)/1000;
-	associated = wl_ext_associated(dev);
-	assoc_info = &cur_if->assoc_info;
 
 	if (connecting && diff_ms < STA_CONNECT_TIMEOUT &&
 			!wl_get_drv_status(cfg, DISCONNECTING, dev)) {
+		uint32 etype = ntoh32(e->event_type);
+		uint32 status = ntoh32(e->status);
 		if (etype == WLC_E_SET_SSID && (status == WLC_E_STATUS_NO_NETWORKS ||
 				status == WLC_E_STATUS_NO_ACK)) {
-			wl_timer_mod(dhd, &cur_if->reconnect_timer, 0);
-			if (assoc_info->reassoc && associated && !handshaking) {
-				/* There are two cases will come in to retry reassoc:
-				 * 1) reconnect from wpa_supplicant
-				 * 2) fw roam
-				 */
-				if (associated)
-					bzero(&cfg->last_roamed_addr, ETHER_ADDR_LEN);
+			wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0);
+			if (cur_if->assoc_info.reassoc) {
 				WL_MSG(dev->name, "retry reassoc\n");
-				if (wl_handle_reassoc(cfg, dev, assoc_info))
-					goto exit;
-				if (assoc_info->chan_cnt == 0)
-					max_wait_time = STA_CONNECT_FULL_CHAN_TIMEOUT;
-				else
-					max_wait_time = STA_RECONNECT_RETRY_TIMEOUT +
-						(WL_BCAST_SCAN_JOIN_ACTIVE_DWELL_TIME_MS * assoc_info->chan_cnt);
-				max_wait_time = min(max_wait_time, STA_CONNECT_FULL_CHAN_TIMEOUT);
-			}
-			else {
-				/* There is one case will come in to retry join:
-				 * 1) connect from wpa_supplicant
-				 */
-				WL_MSG(dev->name, "retry join\n");
-				if (associated) {
-					bzero(&cfg->last_roamed_addr, ETHER_ADDR_LEN);
-					wl_cfg80211_disassoc(dev, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
+				wl_handle_reassoc(cfg, dev, &cur_if->assoc_info);
+				max_wait_time = STA_RECONNECT_RETRY_TIMEOUT;
+			} else {
+				if (!wl_ext_associated(dev)) {
+					WL_MSG(dev->name, "retry join\n");
+					wl_cfg80211_disassoc(dev, WLAN_REASON_DEAUTH_LEAVING);
+					wl_handle_join(cfg, dev, &cur_if->assoc_info);
+					max_wait_time = STA_CONNECT_RETRY_TIMEOUT;
 				}
-				if (wl_handle_join(cfg, dev, assoc_info))
-					goto exit;
-				if (assoc_info->chan_cnt == 0)
-					max_wait_time = STA_CONNECT_FULL_CHAN_TIMEOUT;
-				else
-					max_wait_time = STA_CONNECT_RETRY_TIMEOUT +
-						(WL_BCAST_SCAN_JOIN_ACTIVE_DWELL_TIME_MS * assoc_info->chan_cnt);
-				max_wait_time = min(max_wait_time, STA_CONNECT_FULL_CHAN_TIMEOUT);
 			}
-			IAPSTA_INFO(dev->name, "reconnect %dms later\n", max_wait_time);
-			wl_timer_mod(dhd, &cur_if->reconnect_timer, max_wait_time);
+			wl_ext_mod_timer(&cur_if->reconnect_timer, 0, max_wait_time);
 		}
-		ret = BCME_ERROR;
+		ret = -EAGAIN;
 	}
-#ifdef WL_EXT_DISCONNECT_RECONNECT
-	else if (cur_if->conn_state >= CONN_STATE_CONNECTED &&
-			!wl_get_drv_status(cfg, DISCONNECTING, dev) &&
-			wl_get_drv_status(cfg, CONNECTED, dev)) {
-		if (etype == WLC_E_DISASSOC_IND || etype == WLC_E_DEAUTH_IND) {
-			/* There is one case will come in to retry join:
-			 * 1) receive disconnect from AP after connected
-			 */
-			if (wl_ext_disc_recon_retry(apsta_params, cur_if)) {
-				int wpa_auth = 0;
-				WL_MSG(dev->name, "retry join cnt %d\n", cur_if->sta_disc_recon_cnt);
-				bzero(&cfg->last_roamed_addr, ETHER_ADDR_LEN);
-				wl_ext_update_assoc_info(dev, FALSE);
-#ifdef DHD_LOSSLESS_ROAMING
-				wl_ext_send_event_msg(dev, WLC_E_ROAM_PREP, WLC_E_STATUS_SUCCESS, WLC_E_REASON_DEAUTH);
-#endif
-				if (wl_handle_join(cfg, dev, assoc_info))
-					goto exit;
-				wl_timer_mod(dhd, &cur_if->connect_timer, STA_CONNECT_TIMEOUT);
-				osl_do_gettimeofday(sta_conn_ts);
-				wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_CONNECTING);
-				wl_ext_iovar_getint(dev, "wpa_auth", &wpa_auth);
-				if (!(wpa_auth & (WPA3_AUTH_SAE_PSK|0x20))) {
-					if (assoc_info->chan_cnt == 0)
-						max_wait_time = STA_CONNECT_FULL_CHAN_TIMEOUT;
-					else
-						max_wait_time = STA_CONNECT_RETRY_TIMEOUT +
-							(WL_BCAST_SCAN_JOIN_ACTIVE_DWELL_TIME_MS * assoc_info->chan_cnt);
-					max_wait_time = min(max_wait_time, STA_CONNECT_FULL_CHAN_TIMEOUT);
-					IAPSTA_INFO(dev->name, "reconnect %dms later\n", max_wait_time);
-					wl_timer_mod(dhd, &cur_if->reconnect_timer, max_wait_time);
-				}
-				ret = BCME_ERROR;
-			}
-			else {
-				WL_MSG(dev->name, "out of retry cnt %d within %dms\n",
-					cur_if->sta_disc_recon_cnt, STA_DISCONNECT_RECONNECT_TIMEOUT);
-			}
-		}
-	}
-#endif /* WL_EXT_DISCONNECT_RECONNECT */
-
-exit:
 	mutex_unlock(&cfg->connect_sync);
 	mutex_lock(&apsta_params->in4way_sync);
 
@@ -2895,7 +2553,6 @@
 static void
 wl_ext_set_connect_retry(struct net_device *dev, void *context)
 {
-	struct dhd_pub *dhd = dhd_get_pub(dev);
 	wlcfg_assoc_info_t *assoc_info = (wlcfg_assoc_info_t *)context;
 	struct wl_if_info *cur_if;
 	int max_wait_time;
@@ -2905,20 +2562,18 @@
 	if (!cur_if)
 		return;
 
-	wl_timer_mod(dhd, &cur_if->reconnect_timer, 0);
+	wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0);
 	memset(&cur_if->assoc_info, 0, sizeof(wlcfg_assoc_info_t));
 	wl_ext_iovar_getint(dev, "wpa_auth", &wpa_auth);
 	if (!(wpa_auth & (WPA3_AUTH_SAE_PSK|0x20) && assoc_info)) {
 		memcpy(&cur_if->bssid, assoc_info->bssid, ETHER_ADDR_LEN);
 		memcpy(&cur_if->assoc_info, assoc_info, sizeof(wlcfg_assoc_info_t));
-		if (assoc_info->chan_cnt == 0)
-			max_wait_time = STA_CONNECT_FULL_CHAN_TIMEOUT;
-		else if (assoc_info->reassoc)
+		if (assoc_info->reassoc)
 			max_wait_time = STA_RECONNECT_RETRY_TIMEOUT;
 		else
 			max_wait_time = STA_CONNECT_RETRY_TIMEOUT;
 		IAPSTA_INFO(dev->name, "reconnect %dms later\n", max_wait_time);
-		wl_timer_mod(dhd, &cur_if->reconnect_timer, max_wait_time);
+		wl_ext_mod_timer(&cur_if->reconnect_timer, 0, max_wait_time);
 	}
 }
 #endif /* WL_EXT_RECONNECT */
@@ -3296,7 +2951,7 @@
 #ifdef BCMDBUS
 	if (!rx)
 #endif /* BCMDBUS */
-	wl_timer_mod(dhd, &cur_if->eapol_timer, 0);
+	wl_ext_mod_timer(&cur_if->eapol_timer, 0, 0);
 
 	if (cur_if->pend_eapol_pkt) {
 		PKTCFREE(dhd->osh, cur_if->pend_eapol_pkt, TRUE);
@@ -3355,7 +3010,7 @@
 #else
 				interval = STA_EAPOL_TIMEOUT;
 #endif /* EAPOL_DYNAMATIC_RESEND */
-				wl_timer_mod(dhd, &cur_if->eapol_timer, interval);
+				wl_ext_mod_timer(&cur_if->eapol_timer, 0, interval);
 				IAPSTA_TRACE(cur_if->dev->name, "backup eapol pkt\n");
 			}
 			spin_unlock_irqrestore(&apsta_params->eapol_lock, flags);
@@ -3389,7 +3044,7 @@
 					cur_if->eapol_max_intvl, STA_EAPOL_TIMEOUT,
 					cur_if->eapol_cnt);
 #else
-				IAPSTA_INFO(dev->name, "resend eapol pkt %dms\n", STA_EAPOL_TIMEOUT);
+				IAPSTA_INFO(dev->name, "resend eapol pkt %d\n", STA_EAPOL_TIMEOUT);
 #endif /* EAPOL_DYNAMATIC_RESEND */
 				pending = TRUE;
 			}
@@ -3425,106 +3080,11 @@
 }
 #endif /* EAPOL_RESEND */
 
-#ifdef KEY_INSTALL_CHECK
-static void
-wl_ext_key_install_timeout(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct dhd_pub *dhd;
-	wl_event_msg_t msg;
-
-	if (!dev) {
-		IAPSTA_ERROR("wlan", "dev is not ready\n");
-		return;
-	}
-
-	dhd = dhd_get_pub(dev);
-
-	bzero(&msg, sizeof(wl_event_msg_t));
-	IAPSTA_TRACE(dev->name, "timer expired\n");
-
-	msg.ifidx = dhd_net2idx(dhd->info, dev);
-	msg.event_type = hton32(WLC_E_RESERVED);
-	msg.reason = hton32(ISAM_RC_KEY_INSTALL);
-	wl_ext_event_send(dhd->event_params, &msg, NULL);
-}
-
-static void
-wl_ext_key_install_handler(struct wl_if_info *cur_if,
-	const wl_event_msg_t *e, void *data)
-{
-	struct net_device *dev = cur_if->dev;
-	struct dhd_pub *dhd = dhd_get_pub(dev);
-	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
-	uint32 etype = ntoh32(e->event_type);
-	uint32 reason = ntoh32(e->reason);
-	int err, key_installed = 0;
-
-	if (etype == WLC_E_RESERVED && reason == ISAM_RC_KEY_INSTALL) {
-		if (cur_if->conn_state >= CONN_STATE_4WAY_M4 &&
-				!wl_get_drv_status(cfg, DISCONNECTING, dev) &&
-				wl_get_drv_status(cfg, CONNECTED, dev)) {
-			err = wldev_iovar_getint(dev, "buf_key_b4_m4_installed", &key_installed);
-			if (!err && !key_installed) {
-				cur_if->key_install_cnt++;
-				if (cur_if->key_install_cnt > STA_KEY_INSTALL_MAX) {
-					IAPSTA_ERROR(dev->name, "key not installed, send disconnect\n");
-#ifdef EAPOL_RESEND
-					wl_ext_release_eapol_txpkt(dhd, cur_if->ifidx, FALSE);
-#endif /* EAPOL_RESEND */
-					wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_CONNECTED);
-					wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
-					wl_timer_mod(dhd, &cur_if->key_install_timer, 0);
-					cur_if->key_install_cnt = 0;
-				} else {
-					IAPSTA_INFO(dev->name, "check key installed %dms later, cnt=%d\n",
-						STA_KEY_INSTALL_INTERVAL, cur_if->key_install_cnt);
-					wl_timer_mod(dhd, &cur_if->key_install_timer, STA_KEY_INSTALL_INTERVAL);
-				}
-			} else {
-#ifdef EAPOL_RESEND
-				wl_ext_release_eapol_txpkt(dhd, cur_if->ifidx, FALSE);
-#endif /* EAPOL_RESEND */
-				IAPSTA_INFO(dev->name, "key installed\n");
-				wl_timer_mod(dhd, &cur_if->connect_timer, 0);
-				wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_CONNECTED);
-				cur_if->key_install_cnt = 0;
-			}
-		}
-	}
-	return;
-}
-
-static int
-wl_key_installed(struct wl_if_info *cur_if)
-{
-	struct net_device *dev = cur_if->dev;
-	dhd_pub_t *dhd = dhd_get_pub(dev);
-	int err, key_installed = 0;
-
-	err = wldev_iovar_getint(dev, "buf_key_b4_m4_installed", &key_installed);
-	if (err) {
-		IAPSTA_INFO(dev->name, "not supported %d\n", err);
-		key_installed = 1;
-	} else if (key_installed)
-		IAPSTA_INFO(dev->name, "key installed\n");
-
-	if (key_installed)
-		wl_timer_mod(dhd, &cur_if->key_install_timer, 0);
-	else {
-		IAPSTA_INFO(dev->name, "check key installed %dms later\n", STA_KEY_INSTALL_INTERVAL);
-		wl_timer_mod(dhd, &cur_if->key_install_timer, STA_KEY_INSTALL_INTERVAL);
-	}
-
-	return key_installed;
-}
-#endif /* KEY_INSTALL_CHECK */
-
 #if defined(WL_CFG80211) && defined(SCAN_SUPPRESS)
 static void
 wl_ext_light_scan_prep(struct net_device *dev, void *scan_params, bool scan_v2)
 {
-	wl_scan_params_v1_t *params = NULL;
+	wl_scan_params_t *params = NULL;
 	wl_scan_params_v2_t *params_v2 = NULL;
 
 	if (!scan_params) {
@@ -3536,7 +3096,7 @@
 	if (scan_v2) {
 		params_v2 = (wl_scan_params_v2_t *)scan_params;
 	} else {
-		params = (wl_scan_params_v1_t *)scan_params;
+		params = (wl_scan_params_t *)scan_params;
 	}
 
 	if (params_v2) {
@@ -3570,7 +3130,7 @@
 		tmp_if = &apsta_params->if_info[i];
 		if (tmp_if->dev && (tmp_if->tput_info.tput_tx + tmp_if->tput_info.tput_rx) > tput_sum) {
 			memset(chan_info, 0, sizeof(struct wl_chan_info));
-			wl_ext_get_chan(tmp_if->dev, chan_info);
+			wl_ext_get_chan(apsta_params, tmp_if->dev, chan_info);
 			if (chan_info->chan) {
 				max_tput_if = tmp_if;
 				tput_sum = tmp_if->tput_info.tput_tx + tmp_if->tput_info.tput_rx;
@@ -3709,6 +3269,7 @@
 			}
 		}
 	}
+
 }
 
 static void
@@ -3716,7 +3277,7 @@
 	enum wl_ext_status status)
 {
 	struct net_device *dev = cur_if->dev;
-	struct osl_timespec cur_ts, *sta_disc_ts = &cur_if->sta_disc_ts;
+	struct osl_timespec cur_ts, *sta_disc_ts = &apsta_params->sta_disc_ts;
 	int max_wait_time = 200, max_wait_cnt = 20;
 	int cur_conn_state = cur_if->conn_state;
 	uint32 diff_ms = 0;
@@ -3766,7 +3327,8 @@
 
 	if (suspend) {
 		if (insuspend & AP_DOWN_IN_SUSPEND) {
-			cur_if->chan_info.chan = wl_ext_get_chan(cur_if->dev, &cur_if->chan_info);
+			cur_if->chan_info.chan = wl_ext_get_chan(apsta_params, cur_if->dev,
+				&cur_if->chan_info);
 			if (cur_if->chan_info.chan)
 				wl_ext_if_down(apsta_params, cur_if);
 		}
@@ -3789,7 +3351,7 @@
 
 #ifdef TPUT_MONITOR
 	if (suspend)
-		wl_timer_mod(dhd, &apsta_params->monitor_timer, 0);
+		wl_ext_mod_timer(&apsta_params->monitor_timer, 0, 0);
 #endif /* TPUT_MONITOR */
 
 	for (i=0; i<MAX_IF_NUM; i++) {
@@ -3808,7 +3370,7 @@
 
 #ifdef TPUT_MONITOR
 	if (!suspend)
-		wl_timer_mod(dhd, &apsta_params->monitor_timer, dhd->conf->tput_monitor_ms);
+		wl_ext_mod_timer(&apsta_params->monitor_timer, 0, dhd->conf->tput_monitor_ms);
 #endif /* TPUT_MONITOR */
 
 	return 0;
@@ -3821,11 +3383,11 @@
 	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
 	struct dhd_conf *conf = dhd->conf;
 	struct net_device *dev = cur_if->dev;
-	struct osl_timespec cur_ts, *sta_disc_ts = &cur_if->sta_disc_ts;
-	struct osl_timespec *sta_conn_ts = &cur_if->sta_conn_ts;
+	struct osl_timespec cur_ts, *sta_disc_ts = &apsta_params->sta_disc_ts;
+	struct osl_timespec *sta_conn_ts = &apsta_params->sta_conn_ts;
 	uint32 diff_ms = 0;
-	int ret = 0, suppressed = 0, wpa_auth = 0, max_wait_time = 0, key_installed = 1;
-	uint cur_conn_state, conn_state;
+	int ret = 0, cur_conn_state;
+	int suppressed = 0, wpa_auth = 0;
 	bool connecting = FALSE;
 	wl_event_msg_t *e = (wl_event_msg_t *)context;
 #ifdef WL_CFG80211
@@ -3876,8 +3438,7 @@
 				osl_do_gettimeofday(&cur_ts);
 				diff_ms = osl_do_gettimediff(&cur_ts, sta_conn_ts)/1000;
 				if (connecting && diff_ms <= STA_CONNECT_TIMEOUT) {
-					IAPSTA_ERROR(dev->name, "scan during connecting... %d\n",
-						cur_conn_state);
+					IAPSTA_ERROR(dev->name, "connecting... %d\n", cur_conn_state);
 					ret = -EBUSY;
 					break;
 				}
@@ -3891,15 +3452,24 @@
 				if (wl_get_drv_status(cfg, CONNECTING, dev) ||
 						(connecting && diff_ms <= STA_CONNECT_TIMEOUT) ||
 						(cur_if->empty_scan >= STA_EMPTY_SCAN_MAX)) {
+					unsigned long flags = 0;
 					cur_if->empty_scan = 0;
-					WL_MSG(dev->name, "FAKE SCAN\n");
-					ret = -EBUSY;
+					spin_lock_irqsave(&dhd->up_lock, flags);
+					if (dhd->up) {
+						wl_event_msg_t msg;
+						bzero(&msg, sizeof(wl_event_msg_t));
+						msg.event_type = hton32(WLC_E_ESCAN_RESULT);
+						msg.status = hton32(WLC_E_STATUS_SUCCESS);
+						WL_MSG(dev->name, "FAKE SCAN\n");
+						wl_cfg80211_event(dev, &msg, NULL);
+						ret = -EBUSY;
+					}
+					spin_unlock_irqrestore(&dhd->up_lock, flags);
 				}
 			}
 			break;
 		case WL_EXT_STATUS_SCAN_COMPLETE:
-			if ((conf->war & FW_REINIT_EMPTY_SCAN) &&
-					cfg->bss_list->count == 0 && !p2p_scan(cfg)) {
+			if ((conf->war & FW_REINIT_EMPTY_SCAN) && cfg->bss_list->count == 0) {
 				bool assoc;
 				osl_do_gettimeofday(&cur_ts);
 				diff_ms = osl_do_gettimediff(&cur_ts, sta_disc_ts)/1000;
@@ -3924,26 +3494,18 @@
 			}
 			break;
 #endif /* WL_CFG80211 */
-		case WL_EXT_STATUS_PRE_DISCONNECTING:
+		case WL_EXT_STATUS_DISCONNECTING:
 #ifdef EAPOL_RESEND
 			wl_ext_release_eapol_txpkt(dhd, cur_if->ifidx, FALSE);
 #endif /* EAPOL_RESEND */
-#ifdef KEY_INSTALL_CHECK
-			wl_timer_mod(dhd, &cur_if->key_install_timer, 0);
-#endif /* KEY_INSTALL_CHECK */
-			wl_timer_mod(dhd, &cur_if->connect_timer, 0);
+			wl_ext_mod_timer(&cur_if->connect_timer, 0, 0);
 #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
-			wl_timer_mod(dhd, &cur_if->reconnect_timer, 0);
+			wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0);
 			memset(&cur_if->assoc_info, 0, sizeof(wlcfg_assoc_info_t));
-#ifdef WL_EXT_DISCONNECT_RECONNECT
-			cur_if->sta_disc_recon_cnt = 0;
-#endif /* WL_EXT_DISCONNECT_RECONNECT */
 #endif /* WL_EXT_RECONNECT && WL_CFG80211 */
 #ifdef SCAN_SUPPRESS
 			apsta_params->scan_busy_cnt = 0;
 #endif /* SCAN_SUPPRESS */
-			break;
-		case WL_EXT_STATUS_DISCONNECTING:
 			if (connecting) {
 				IAPSTA_ERROR(dev->name, "connect failed at %d\n", cur_conn_state);
 				wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_IDLE);
@@ -3951,9 +3513,6 @@
 			if (action & STA_NO_BTC_IN4WAY) {
 				wl_set_btc_in4way(apsta_params, cur_if, status, FALSE);
 			}
-#ifdef BTC_WAR
-			wl_ext_btc_config(cur_if->dev, FALSE);
-#endif /* BTC_WAR */
 			if (action & STA_WAIT_DISCONNECTED) {
 				wl_wait_disconnect(apsta_params, cur_if, status);
 				wake_up_interruptible(&conf->event_complete);
@@ -3964,11 +3523,8 @@
 			if (action & STA_REASSOC_RETRY) {
 				wl_ext_set_connect_retry(dev, context);
 			}
-#ifdef WL_EXT_DISCONNECT_RECONNECT
-			cur_if->sta_disc_recon_cnt = 0;
-#endif /* WL_EXT_DISCONNECT_RECONNECT */
 #endif /* WL_EXT_RECONNECT && WL_CFG80211 */
-			wl_timer_mod(dhd, &cur_if->connect_timer, STA_CONNECT_TIMEOUT);
+			wl_ext_mod_timer(&cur_if->connect_timer, 0, STA_CONNECT_TIMEOUT);
 			osl_do_gettimeofday(sta_conn_ts);
 			wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_CONNECTING);
 			if (action & STA_NO_BTC_IN4WAY) {
@@ -3978,18 +3534,12 @@
 		case WL_EXT_STATUS_CONNECTED:
 			wl_ext_iovar_getint(dev, "wpa_auth", &wpa_auth);
 			if ((wpa_auth < WPA_AUTH_UNSPECIFIED) || (wpa_auth & WPA2_AUTH_FT)) {
-				wl_timer_mod(dhd, &cur_if->connect_timer, 0);
+				wl_ext_mod_timer(&cur_if->connect_timer, 0, 0);
 				wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_CONNECTED);
-#ifdef BTC_WAR
-				wl_ext_btc_config(cur_if->dev, TRUE);
-#endif /* BTC_WAR */
-				max_wait_time = 0;
-			} else {
-				max_wait_time = STA_4WAY_TIMEOUT;
 			}
 #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
-			wl_ext_update_assoc_info(dev, TRUE);
-			wl_timer_mod(dhd, &cur_if->reconnect_timer, max_wait_time);
+			wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0);
+			memset(&cur_if->assoc_info, 0, sizeof(wlcfg_assoc_info_t));
 #endif /* WL_EXT_RECONNECT && WL_CFG80211 */
 			if (cur_if->ifmode == ISTA_MODE) {
 				dhd_conf_set_wme(dhd, cur_if->ifidx, 0);
@@ -3997,31 +3547,6 @@
 			}
 			else if (cur_if->ifmode == IGC_MODE) {
 				dhd_conf_set_mchan_bw(dhd, WL_P2P_IF_CLIENT, -1);
-			}
-			break;
-		case WL_EXT_STATUS_ROAMED:
-			wl_ext_iovar_getint(dev, "wpa_auth", &wpa_auth);
-			if ((wpa_auth >= WPA_AUTH_UNSPECIFIED) && !(wpa_auth & WPA2_AUTH_FT)) {
-				wl_timer_mod(dhd, &cur_if->connect_timer, STA_CONNECT_TIMEOUT);
-				osl_do_gettimeofday(sta_conn_ts);
-				wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_CONNECTING);
-#ifdef BTC_WAR
-				wl_ext_btc_config(cur_if->dev, TRUE);
-#endif /* BTC_WAR */
-				max_wait_time = STA_4WAY_TIMEOUT;
-			} else {
-				max_wait_time = 0;
-			}
-#if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
-			wl_ext_update_assoc_info(dev, TRUE);
-			wl_timer_mod(dhd, &cur_if->reconnect_timer, max_wait_time);
-#endif /* WL_EXT_RECONNECT && WL_CFG80211 */
-#ifdef KEY_INSTALL_CHECK
-			wl_timer_mod(dhd, &cur_if->key_install_timer, 0);
-#endif /* KEY_INSTALL_CHECK */
-			if (cur_if->ifmode == ISTA_MODE) {
-				dhd_conf_set_wme(dhd, cur_if->ifidx, 0);
-				wake_up_interruptible(&conf->event_complete);
 			}
 			break;
 		case WL_EXT_STATUS_RECONNECT:
@@ -4038,15 +3563,9 @@
 #ifdef EAPOL_RESEND
 			wl_ext_release_eapol_txpkt(dhd, cur_if->ifidx, FALSE);
 #endif /* EAPOL_RESEND */
-#ifdef KEY_INSTALL_CHECK
-			wl_timer_mod(dhd, &cur_if->key_install_timer, 0);
-#endif /* KEY_INSTALL_CHECK */
 #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
-			wl_timer_mod(dhd, &cur_if->reconnect_timer, 0);
+			wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0);
 			memset(&cur_if->assoc_info, 0, sizeof(wlcfg_assoc_info_t));
-#ifdef WL_EXT_DISCONNECT_RECONNECT
-			cur_if->sta_disc_recon_cnt = 0;
-#endif /* WL_EXT_DISCONNECT_RECONNECT */
 #endif /* WL_EXT_RECONNECT && WL_CFG80211 */
 #ifdef SCAN_SUPPRESS
 			apsta_params->scan_busy_cnt = 0;
@@ -4055,7 +3574,7 @@
 					!(ntoh16(e->flags) & WLC_EVENT_MSG_LINK)) {
 				apsta_params->linkdown_reason = ntoh32(e->reason);
 			}
-			wl_timer_mod(dhd, &cur_if->connect_timer, 0);
+			wl_ext_mod_timer(&cur_if->connect_timer, 0, 0);
 			if (connecting) {
 				IAPSTA_ERROR(dev->name, "connect failed at %d\n", cur_conn_state);
 			}
@@ -4063,37 +3582,23 @@
 			if (action & STA_NO_BTC_IN4WAY) {
 				wl_set_btc_in4way(apsta_params, cur_if, status, FALSE);
 			}
-#ifdef BTC_WAR
-			wl_ext_btc_config(cur_if->dev, FALSE);
-#endif /* BTC_WAR */
 			osl_do_gettimeofday(sta_disc_ts);
 			wake_up_interruptible(&conf->event_complete);
 			break;
 		case WL_EXT_STATUS_ADD_KEY:
-			conn_state = CONN_STATE_ADD_KEY;
-			wl_timer_mod(dhd, &cur_if->connect_timer, 0);
-#if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
-			wl_timer_mod(dhd, &cur_if->reconnect_timer, 0);
-#endif /* WL_EXT_RECONNECT && WL_CFG80211 */
-#ifdef KEY_INSTALL_CHECK
-			key_installed = wl_key_installed(cur_if);
-#endif /* KEY_INSTALL_CHECK */
-			if (key_installed)
-				conn_state = CONN_STATE_CONNECTED;
-			wl_ext_update_conn_state(dhd, cur_if->ifidx, conn_state);
-			IAPSTA_INFO(dev->name, "WPA 4-WAY complete %d => %d\n",
-				cur_conn_state, conn_state);
+			wl_ext_mod_timer(&cur_if->connect_timer, 0, 0);
+			wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_CONNECTED);
 #ifdef EAPOL_RESEND
-			if (key_installed)
-				wl_ext_release_eapol_txpkt(dhd, cur_if->ifidx, FALSE);
+			wl_ext_release_eapol_txpkt(dhd, cur_if->ifidx, FALSE);
 #endif /* EAPOL_RESEND */
+#if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
+			wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0);
+#endif /* WL_EXT_RECONNECT && WL_CFG80211 */
 			if (action & STA_NO_BTC_IN4WAY) {
 				wl_set_btc_in4way(apsta_params, cur_if, status, FALSE);
 			}
-#ifdef BTC_WAR
-			wl_ext_btc_config(cur_if->dev, TRUE);
-#endif /* BTC_WAR */
 			wake_up_interruptible(&conf->event_complete);
+			IAPSTA_INFO(dev->name, "WPA 4-WAY complete %d\n", cur_conn_state);
 			break;
 		default:
 			IAPSTA_INFO(dev->name, "Unknown action=0x%x, status=%d\n", action, status);
@@ -4109,8 +3614,8 @@
 {
 	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
 	struct net_device *dev = cur_if->dev;
-	struct osl_timespec cur_ts, *ap_disc_sta_ts = &cur_if->ap_disc_sta_ts;
-	u8 *ap_disc_sta_bssid = (u8*)&cur_if->ap_disc_sta_bssid;
+	struct osl_timespec cur_ts, *ap_disc_sta_ts = &apsta_params->ap_disc_sta_ts;
+	u8 *ap_disc_sta_bssid = (u8*)&apsta_params->ap_disc_sta_bssid;
 	uint32 diff_ms = 0, timeout, max_wait_time = 300;
 	int ret = 0, suppressed = 0;
 	u8* mac_addr = context;
@@ -4131,12 +3636,12 @@
 			break;
 		case WL_EXT_STATUS_AP_ENABLING:
 #ifdef RESTART_AP_WAR
-			wl_timer_mod(dhd, &cur_if->restart_ap_timer, AP_RESTART_TIMEOUT);
+			wl_ext_mod_timer(&cur_if->restart_ap_timer, AP_RESTART_TIMEOUT, 0);
 #endif /* RESTART_AP_WAR */
 			break;
 		case WL_EXT_STATUS_AP_ENABLED:
 #ifdef RESTART_AP_WAR
-			wl_timer_mod(dhd, &cur_if->restart_ap_timer, 0);
+			wl_ext_mod_timer(&cur_if->restart_ap_timer, 0, 0);
 #endif /* RESTART_AP_WAR */
 			if (cur_if->ifmode == IAP_MODE)
 				dhd_conf_set_wme(dhd, cur_if->ifidx, 1);
@@ -4145,7 +3650,7 @@
 			break;
 		case WL_EXT_STATUS_AP_DISABLING:
 #ifdef RESTART_AP_WAR
-			wl_timer_mod(dhd, &cur_if->restart_ap_timer, 0);
+			wl_ext_mod_timer(&cur_if->restart_ap_timer, 0, 0);
 #endif /* RESTART_AP_WAR */
 			break;
 		case WL_EXT_STATUS_DELETE_STA:
@@ -4163,13 +3668,13 @@
 				}
 				if (wait) {
 					IAPSTA_INFO(dev->name, "status=%d, ap_recon_sta=%d, waiting %dms ...\n",
-						status, cur_if->ap_recon_sta, max_wait_time);
+						status, apsta_params->ap_recon_sta, max_wait_time);
 					mutex_unlock(&apsta_params->in4way_sync);
-					timeout = wait_event_interruptible_timeout(cur_if->ap_recon_sta_event,
-						cur_if->ap_recon_sta, msecs_to_jiffies(max_wait_time));
+					timeout = wait_event_interruptible_timeout(apsta_params->ap_recon_sta_event,
+						apsta_params->ap_recon_sta, msecs_to_jiffies(max_wait_time));
 					mutex_lock(&apsta_params->in4way_sync);
 					IAPSTA_INFO(dev->name, "status=%d, ap_recon_sta=%d, timeout=%d\n",
-						status, cur_if->ap_recon_sta, timeout);
+						status, apsta_params->ap_recon_sta, timeout);
 					if (timeout > 0) {
 						IAPSTA_INFO(dev->name, "skip delete STA %pM\n", mac_addr);
 						ret = -1;
@@ -4177,8 +3682,8 @@
 					}
 				} else {
 					IAPSTA_INFO(dev->name, "status=%d, ap_recon_sta=%d => 0\n",
-						status, cur_if->ap_recon_sta);
-					cur_if->ap_recon_sta = FALSE;
+						status, apsta_params->ap_recon_sta);
+					apsta_params->ap_recon_sta = FALSE;
 					if (cur_if->ifmode == IGO_MODE)
 						wl_ext_update_conn_state(dhd, cur_if->ifidx, CONN_STATE_IDLE);
 				}
@@ -4187,10 +3692,10 @@
 		case WL_EXT_STATUS_STA_DISCONNECTED:
 			if (action & AP_WAIT_STA_RECONNECT) {
 				IAPSTA_INFO(dev->name, "latest disc STA %pM ap_recon_sta=%d\n",
-					ap_disc_sta_bssid, cur_if->ap_recon_sta);
+					ap_disc_sta_bssid, apsta_params->ap_recon_sta);
 				osl_do_gettimeofday(ap_disc_sta_ts);
 				memcpy(ap_disc_sta_bssid, mac_addr, ETHER_ADDR_LEN);
-				cur_if->ap_recon_sta = FALSE;
+				apsta_params->ap_recon_sta = FALSE;
 			}
 			break;
 		case WL_EXT_STATUS_STA_CONNECTED:
@@ -4200,11 +3705,11 @@
 				if (diff_ms < max_wait_time &&
 						!memcmp(ap_disc_sta_bssid, mac_addr, ETHER_ADDR_LEN)) {
 					IAPSTA_INFO(dev->name, "status=%d, ap_recon_sta=%d => 1\n",
-						status, cur_if->ap_recon_sta);
-					cur_if->ap_recon_sta = TRUE;
-					wake_up_interruptible(&cur_if->ap_recon_sta_event);
+						status, apsta_params->ap_recon_sta);
+					apsta_params->ap_recon_sta = TRUE;
+					wake_up_interruptible(&apsta_params->ap_recon_sta_event);
 				} else {
-					cur_if->ap_recon_sta = FALSE;
+					apsta_params->ap_recon_sta = FALSE;
 				}
 			}
 			break;
@@ -4302,8 +3807,7 @@
 			}
 		}
 	} else {
-		IAPSTA_ERROR(dev->name, "Unknown auth_alg=%d or auth_seq=%d\n",
-			auth_alg, auth_seq);
+		WL_ERR(("Unknown auth_alg=%d or auth_seq=%d\n", auth_alg, auth_seq));
 	}
 
 	return;
@@ -4383,150 +3887,6 @@
 	return maxassoc;
 }
 
-static int
-dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len)
-{
-	struct dhd_pub *dhd = dhd_get_pub(dev);
-	dhd_ioctl_t ioc;
-	int8 index;
-	int ret;
-
-	memset(&ioc, 0, sizeof(ioc));
-	ioc.cmd = cmd;
-	ioc.buf = arg;
-	ioc.len = len;
-
-	index = dhd_net2idx(dhd->info, dev);
-	if (index == DHD_BAD_IF) {
-		IAPSTA_ERROR(dev->name, "Bad ifidx from dev\n");
-		return -ENODEV;
-	}
-	ret = dhd_ioctl_process(dhd, index, &ioc, arg);
-
-	return ret;
-}
-
-static void
-wl_ampdu_dump(struct net_device *dev)
-{
-	char *ioctl_buf = g_ioctl_buf, *buf = NULL;
-	char *tx_pch_start, *tx_pch_end, *rx_pch_start, *rx_pch_end;
-	int ret = 0, max_len, tx_len, rx_len;
-
-	if (!(android_msg_level & ANDROID_AMPDU_LEVEL))
-		return;
-
-	memset(ioctl_buf, 0, WL_DUMP_BUF_LEN);
-	ret = bcm_mkiovar("dump", "ampdu", strlen("ampdu"), ioctl_buf, WL_DUMP_BUF_LEN);
-	if (ret == 0) {
-		goto exit;
-	}
-	ret = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctl_buf, WL_DUMP_BUF_LEN);
-	if (ret) {
-		goto exit;
-	}
-
-	buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL);
-	if (buf == NULL) {
-		IAPSTA_ERROR(dev->name, "Failed to allocate buffer of %d bytes\n", WLC_IOCTL_MEDLEN);
-		goto exit;
-	}
-	memset(buf, 0, WLC_IOCTL_MEDLEN);
-	ret = bcm_mkiovar("dump_clear", "ampdu", strlen("ampdu"), buf, WLC_IOCTL_MEDLEN);
-	if (ret == 0) {
-		goto exit;
-	}
-	ret = dev_wlc_ioctl(dev, WLC_SET_VAR, (void *)buf, WLC_IOCTL_MEDLEN);
-	if (ret) {
-		goto exit;
-	}
-
-	tx_pch_start = strstr(ioctl_buf, "TX MCS");
-	tx_pch_end = strstr(ioctl_buf, "HEMU");
-	rx_pch_start = strstr(ioctl_buf, "RX MCS");
-	rx_pch_end = strstr(ioctl_buf, "RX MCS SGI");
-	max_len = (tx_pch_end-tx_pch_start) + (rx_pch_end-rx_pch_start);
-	if (max_len > (WLC_IOCTL_MEDLEN-1))
-		goto exit;
-
-	tx_len = tx_pch_end - tx_pch_start;
-	rx_len = rx_pch_end - rx_pch_start;
-
-	memset(buf, 0, WLC_IOCTL_MEDLEN);
-	memcpy(buf, tx_pch_start, tx_len);
-	memcpy(buf+tx_len, rx_pch_start, rx_len);
-	WL_MSG(dev->name,"\n%s\n", buf);
-
-exit:
-	if (buf)
-		kfree(buf);
-}
-
-static void
-wl_btc_dump(struct net_device *dev)
-{
-	struct dhd_pub *dhd = dhd_get_pub(dev);
-	int ret, val;
-
-	if (!(android_msg_level & ANDROID_BTC_LEVEL))
-		return;
-
-	ret = dhd_conf_reg2args(dhd, "btc_params", FALSE, 15, &val);
-	if (!ret)
-		WL_MSG(dev->name,"btc_params15=%d\n", val);
-}
-
-static void
-wl_tvpm_dump(struct net_device *dev)
-{
-	wl_tvpm_req_t* tvpm_req = NULL;
-	size_t reqlen = sizeof(wl_tvpm_req_t) + sizeof(wl_tvpm_status_t);
-	uint8 *outbuf = g_ioctl_buf;
-	size_t outlen = WLC_IOCTL_MEDLEN;
-	wl_tvpm_status_t* status;
-	int ret, phy_temp = 0;
-	bool tvpm = FALSE, sense = FALSE;
-
-	if (!(android_msg_level & ANDROID_TVPM_LEVEL))
-		return;
-
-	tvpm_req = kmalloc(reqlen, GFP_KERNEL);
-	if (tvpm_req == NULL) {
-		IAPSTA_ERROR(dev->name, "MALLOC failed\n");
-		goto exit;
-	}
-	memset(tvpm_req, 0, reqlen);
-
-	tvpm_req->version = TVPM_REQ_VERSION_1;
-	tvpm_req->length = reqlen;
-	tvpm_req->req_type = WL_TVPM_REQ_STATUS;
-	ret = wldev_iovar_getbuf(dev, "tvpm", tvpm_req, reqlen, outbuf, outlen, NULL);
-	status = (wl_tvpm_status_t*)outbuf;
-	if (!ret && status->enable) {
-		tvpm = TRUE;
-	} else {
-		ret = wldev_iovar_getbuf(dev, "phy_tempsense", &phy_temp, sizeof(phy_temp),
-			outbuf, outlen, NULL);
-		if (!ret) {
-			phy_temp = dtoh32(*(int*)outbuf);
-			sense = TRUE;
-		}
-	}
-
-	if (tvpm) {
-		WL_MSG(dev->name,"temp=%3d, duty=%3d, pwrbko=%d, chains=%d\n",
-			status->temp, status->tx_dutycycle, status->tx_power_backoff,
-			status->num_active_chains);
-	}
-	else if (sense) {
-		WL_MSG(dev->name,"phy_temp=%3d\n", phy_temp);
-	}
-
-exit:
-	if (tvpm_req)
-		kfree(tvpm_req);
-}
-
 static void
 wl_phy_rssi_ant(struct net_device *dev, struct ether_addr *mac,
 	char *rssi_buf, int len)
@@ -4552,8 +3912,6 @@
 			wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t), 0);
 			rssi_ant_p->count = 1;
 			rssi_ant_p->rssi_ant[0] = dtoh32(scb_val.val);
-		} else {
-			rssi_ant_p->count = 0;
 		}
 	}
 	for (i=0; i<rssi_ant_p->count && rssi_ant_p->rssi_ant[i]; i++) {
@@ -4579,12 +3937,17 @@
 static void
 wl_sta_info_dump(struct net_device *dev, struct ether_addr *mac)
 {
-	void *buf = g_ioctl_buf;
+	void *buf = NULL;
 	sta_info_v4_t *sta = NULL;
 	char rssi_buf[16];
 	int ret;
 	s32 rate = 0;
 
+	buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL);
+	if (buf == NULL) {
+		IAPSTA_ERROR(dev->name, "MALLOC failed\n");
+		goto exit;
+	}
 	memset(rssi_buf, 0, sizeof(rssi_buf));
 	wl_phy_rssi_ant(dev, mac, rssi_buf, sizeof(rssi_buf));
 	ret = wldev_iovar_getbuf(dev, "sta_info", (const void*)mac,
@@ -4592,27 +3955,22 @@
 	if (ret == 0) {
 		sta = (sta_info_v4_t *)buf;
 	}
-	if (sta == NULL || (sta->ver != WL_STA_VER_4 && sta->ver != WL_STA_VER_5 &&
-			sta->ver != WL_STA_VER_6)) {
+	if (sta == NULL || (sta->ver != WL_STA_VER_4 && sta->ver != WL_STA_VER_5)) {
 		wldev_ioctl_get(dev, WLC_GET_RATE, &rate, sizeof(rate));
 		rate = dtoh32(rate);
 		WL_MSG(dev->name,
 			"mac=%pM, rssi=%s, tx_rate:%4d%2s\n",
 			mac, rssi_buf, rate/2, (rate & 1) ? ".5" : "");
 	} else {
-		if (dtoh32(sta->rx_rate) != -1) {
-			WL_MSG(dev->name,
-				"mac=%pM, rssi=%s, tx_rate:%4d.%d, rx_rate:%4d.%d\n",
-				mac, rssi_buf,
-				dtoh32(sta->tx_rate)/1000, ((dtoh32(sta->tx_rate)/100)%10),
-				dtoh32(sta->rx_rate)/1000, ((dtoh32(sta->rx_rate)/100)%10));
-		} else {
-			WL_MSG(dev->name,
-				"mac=%pM, rssi=%s, tx_rate:%4d.%d, rx_rate:%4d\n",
-				mac, rssi_buf,
-				dtoh32(sta->tx_rate)/1000, ((dtoh32(sta->tx_rate)/100)%10),
-				dtoh32(sta->rx_rate));
-		}
+		WL_MSG(dev->name,
+			"mac=%pM, rssi=%s, tx_rate:%4d.%d, rx_rate:%4d.%d\n", mac, rssi_buf,
+			dtoh32(sta->tx_rate)/1000, ((dtoh32(sta->tx_rate)/100)%10),
+			dtoh32(sta->rx_rate)/1000, ((dtoh32(sta->rx_rate)/100)%10));
+	}
+
+exit:
+	if (buf) {
+		kfree(buf);
 	}
 }
 
@@ -4705,11 +4063,10 @@
 }
 
 static void
-wl_tput_monitor_handler(struct wl_if_info *cur_if,
-	const wl_event_msg_t *e, void *data)
+wl_tput_monitor_handler(struct wl_apsta_params *apsta_params,
+	struct wl_if_info *cur_if, const wl_event_msg_t *e, void *data)
 {
-	struct dhd_pub *dhd = dhd_get_pub(cur_if->dev);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
+	struct dhd_pub *dhd = apsta_params->dhd;
 	wl_tput_info_t *tput_info;
 	struct wl_if_info *tmp_if;
 #ifdef WLDWDS
@@ -4730,7 +4087,7 @@
 			tmp_if = &apsta_params->if_info[i];
 			if (tmp_if->dev &&
 					(tmp_if->ifmode == ISTA_MODE || tmp_if->ifmode == IGC_MODE) &&
-					wl_get_isam_status(tmp_if, STA_CONNECTED)) {
+					wl_ext_associated(tmp_if->dev)) {
 				wl_tput_monitor(dhd, tmp_if->ifidx, &tmp_if->tput_info);
 				monitor_if[i] = TRUE;
 			}
@@ -4766,12 +4123,8 @@
 				monitor = TRUE;
 			}
 		}
-		if (monitor) {
-			wl_btc_dump(cur_if->dev);
-			wl_tvpm_dump(cur_if->dev);
-			wl_ampdu_dump(cur_if->dev);
-			wl_timer_mod(dhd, &apsta_params->monitor_timer, timeout);
-		}
+		if (monitor)
+			wl_ext_mod_timer(&apsta_params->monitor_timer, 0, timeout);
 #ifdef BCMSDIO
 		if (apsta_params->tput_sum >= dhd->conf->doflow_tput_thresh && dhd_doflow) {
 			dhd_doflow = FALSE;
@@ -4787,9 +4140,9 @@
 	else if (cur_if->ifmode == ISTA_MODE || cur_if->ifmode == IGC_MODE) {
 		if (etype == WLC_E_LINK) {
 			if (flags & WLC_EVENT_MSG_LINK) {
-				wl_timer_mod(dhd, &apsta_params->monitor_timer, timeout);
+				wl_ext_mod_timer(&apsta_params->monitor_timer, 0, timeout);
 			} else if (!wl_ext_iapsta_other_if_enabled(cur_if->dev)) {
-				wl_timer_mod(dhd, &apsta_params->monitor_timer, 0);
+				wl_ext_mod_timer(&apsta_params->monitor_timer, 0, 0);
 			}
 		}
 	}
@@ -4797,22 +4150,33 @@
 		if ((etype == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) ||
 				(etype == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
 				reason == WLC_E_REASON_INITIAL_ASSOC)) {
-			wl_timer_mod(dhd, &apsta_params->monitor_timer, timeout);
+			wl_ext_mod_timer(&apsta_params->monitor_timer, 0, timeout);
 		} else if ((etype == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS) ||
 				(etype == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
 				reason == WLC_E_REASON_DEAUTH)) {
 			if (!wl_ext_iapsta_other_if_enabled(cur_if->dev)) {
-				wl_timer_mod(dhd, &apsta_params->monitor_timer, 0);
+				wl_ext_mod_timer(&apsta_params->monitor_timer, 0, 0);
 			}
 		} else if ((etype == WLC_E_ASSOC_IND || etype == WLC_E_REASSOC_IND) &&
 				reason == DOT11_SC_SUCCESS) {
-			wl_timer_mod(dhd, &apsta_params->monitor_timer, timeout);
+			wl_ext_mod_timer(&apsta_params->monitor_timer, 0, timeout);
 		}
 	}
 }
 #endif /* TPUT_MONITOR */
 
 #ifdef ACS_MONITOR
+static void
+wl_ext_mod_timer_pending(timer_list_compat_t *timer, uint sec, uint msec)
+{
+	uint timeout = sec * 1000 + msec;
+
+	if (timeout && !timer_pending(timer)) {
+		IAPSTA_TRACE("wlan", "timeout=%d\n", timeout);
+		mod_timer(timer, jiffies + msecs_to_jiffies(timeout));
+	}
+}
+
 static bool
 wl_ext_max_prio_if(struct wl_apsta_params *apsta_params,
 	struct wl_if_info *cur_if)
@@ -4867,7 +4231,7 @@
 	if (apsta_params->acs & ACS_DRV_BIT) {
 		mutex_lock(&apsta_params->usr_sync);
 		memset(&chan_info, 0, sizeof(struct wl_chan_info));
-		wl_ext_get_chan(cur_if->dev, &chan_info);
+		wl_ext_get_chan(apsta_params, cur_if->dev, &chan_info);
 		if (chan_info.chan) {
 			if (chan_info.band == WLC_BAND_5G)
 				cur_if->chan_info.chan = cur_if->escan->best_5g_ch;
@@ -4876,7 +4240,7 @@
 			wl_ext_move_cur_channel(apsta_params, cur_if);
 			if (!wl_ext_same_chan(&cur_if->chan_info, &chan_info)) {
 				WL_MSG(cur_if->dev->name, "move channel %s-%d => %s-%d\n",
-					WLCBAND2STR(chan_info.band), chan_info.chan,
+					WLCBAND2STR(chan_info->band), chan_info.chan,
 					WLCBAND2STR(cur_if->chan_info.band), cur_if->chan_info.chan);
 				wl_ext_if_down(apsta_params, cur_if);
 				wl_ext_move_other_channel(apsta_params, cur_if);
@@ -4925,34 +4289,34 @@
 				(etype == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
 				reason == WLC_E_REASON_INITIAL_ASSOC)) {
 			// Link up
-			wl_timer_mod(dhd, &cur_if->acs_timer, acs_tmo*1000);
+			wl_ext_mod_timer_pending(&cur_if->acs_timer, acs_tmo, 0);
 		}
 		else if ((etype == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS) ||
 				(etype == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
 				reason == WLC_E_REASON_DEAUTH)) {
 			// Link down
-			wl_timer_mod(dhd, &cur_if->acs_timer, 0);
+			wl_ext_mod_timer(&cur_if->acs_timer, 0, 0);
 			cur_if->escan->autochannel = 0;
 		}
 		else if ((etype == WLC_E_ASSOC_IND || etype == WLC_E_REASSOC_IND) &&
 				reason == DOT11_SC_SUCCESS) {
 			// external STA connected
-			wl_timer_mod(dhd, &cur_if->acs_timer, 0);
+			wl_ext_mod_timer(&cur_if->acs_timer, 0, 0);
 		}
 		else if (etype == WLC_E_DISASSOC_IND ||
 				etype == WLC_E_DEAUTH_IND ||
 				(etype == WLC_E_DEAUTH && reason != DOT11_RC_RESERVED)) {
 			// external STA disconnected
-			wl_timer_mod(dhd, &cur_if->acs_timer, acs_tmo*1000);
+			wl_ext_mod_timer_pending(&cur_if->acs_timer, acs_tmo, 0);
 		}
 		else if (etype == WLC_E_RESERVED && reason == ISAM_RC_AP_ACS) {
 			// acs_tmo expired
 			if (!wl_ext_assoclist_num(cur_if->dev) &&
 					!wl_ext_max_prio_if(apsta_params, cur_if)) {
 				wl_ext_acs_scan(apsta_params, cur_if);
-				wl_timer_mod(dhd, &cur_if->acs_timer, acs_tmo*1000);
+				wl_ext_mod_timer(&cur_if->acs_timer, acs_tmo, 0);
 			} else {
-				wl_timer_mod(dhd, &cur_if->acs_timer, 0);
+				wl_ext_mod_timer(&cur_if->acs_timer, 0, 0);
 			}
 		}
 		else if (((etype == WLC_E_ESCAN_RESULT && status == WLC_E_STATUS_SUCCESS) ||
@@ -4966,7 +4330,7 @@
 					!wl_ext_max_prio_if(apsta_params, cur_if)) {
 				wl_ext_acs(apsta_params, cur_if);
 			} else {
-				wl_timer_mod(dhd, &cur_if->acs_timer, 0);
+				wl_ext_mod_timer(&cur_if->acs_timer, 0, 0);
 			}
 		}
 	}
@@ -4976,7 +4340,7 @@
 wl_acs_detach(struct wl_if_info *cur_if)
 {
 	IAPSTA_TRACE(cur_if->dev->name, "Enter\n");
-	wl_timer_deregister(cur_if->dev, &cur_if->acs_timer);
+	del_timer_sync(&cur_if->acs_timer);
 	if (cur_if->escan) {
 		cur_if->escan = NULL;
 	}
@@ -4987,7 +4351,7 @@
 {
 	IAPSTA_TRACE(cur_if->dev->name, "Enter\n");
 	cur_if->escan = dhd->escan;
-	wl_timer_register(cur_if->dev, &cur_if->acs_timer, wl_acs_timer);
+	init_timer_compat(&cur_if->acs_timer, wl_acs_timer, cur_if->dev);
 }
 #endif /* ACS_MONITOR */
 
@@ -5030,7 +4394,7 @@
 				WL_MSG(cur_if->ifname, "restart AP\n");
 				wl_ext_if_down(apsta_params, cur_if);
 				wl_ext_if_up(apsta_params, cur_if, FALSE, 1);
-				wl_timer_mod(dhd, &cur_if->restart_ap_timer, AP_RESTART_TIMEOUT);
+				wl_ext_mod_timer(&cur_if->restart_ap_timer, AP_RESTART_TIMEOUT, 0);
 			} else {
 				WL_MSG(cur_if->ifname, "skip restart AP\n");
 			}
@@ -5119,12 +4483,20 @@
 {
 	struct dhd_pub *dhd = dhd_get_pub(cur_if->dev);
 	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
-	char *iovar_buf = g_ioctl_buf;
+	char *iovar_buf = NULL;
 	uint32 corerev = 0;
 	wl_cnt_info_t *cntinfo;
 	uint16 ver;
 	int ret = 0;
 
+	iovar_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL);
+	if (!iovar_buf) {
+		IAPSTA_ERROR(cur_if->ifname, "no memory\n");
+		ret = BCME_NOMEM;
+		goto exit;
+	}
+
+	memset(iovar_buf, 0, WLC_IOCTL_MEDLEN);
 	ret = wldev_iovar_getbuf(cur_if->dev, "counters", NULL, 0,
 		iovar_buf, WLC_IOCTL_MEDLEN, NULL);
 	if (unlikely(ret)) {
@@ -5137,10 +4509,10 @@
 	cntinfo->datalen = dtoh16(cntinfo->datalen);
 	ver = cntinfo->version;
 	CHK_CNTBUF_DATALEN(iovar_buf, WLC_IOCTL_MEDLEN);
-	if (ver > WL_CNT_VERSION_XTLV) {
+	if (ver > WL_CNT_T_VERSION) {
 		IAPSTA_ERROR(cur_if->ifname,
 			"Incorrect version of counters struct: expected %d; got %d\n",
-			WL_CNT_VERSION_XTLV, ver);
+			WL_CNT_T_VERSION, ver);
 		goto exit;
 	}
 
@@ -5168,6 +4540,9 @@
 	}
 
 exit:
+	if (iovar_buf)
+		kfree(iovar_buf);
+
 	return ret;
 }
 #endif /* RESET_AP_WAR | RXF0OVFL_REINIT_WAR */
@@ -5214,7 +4589,7 @@
 				reason == WLC_E_REASON_INITIAL_ASSOC)) {
 			// Link up
 			wl_ext_counters_update(cur_if, ISAM_RC_AP_RESET);
-			wl_timer_mod(dhd, &cur_if->reset_ap_timer, AP_TXBCNFRM_TIMEOUT);
+			wl_ext_mod_timer(&cur_if->reset_ap_timer, AP_TXBCNFRM_TIMEOUT, 0);
 		}
 		else if (etype == WLC_E_RESERVED && reason == ISAM_RC_AP_RESET) {
 			txbcnfrm = cur_if->txbcnfrm;
@@ -5227,7 +4602,7 @@
 				wl_ext_if_up(apsta_params, cur_if, FALSE, 500);
 			}
 done:
-			wl_timer_mod(dhd, &cur_if->reset_ap_timer, AP_TXBCNFRM_TIMEOUT);
+			wl_ext_mod_timer(&cur_if->reset_ap_timer, AP_TXBCNFRM_TIMEOUT, 0);
 		}
 	}
 	return;
@@ -5275,7 +4650,7 @@
 			(etype == WLC_E_LINK) && (flags & WLC_EVENT_MSG_LINK)) {
 		// Link up
 		wl_ext_counters_update(cur_if, ISAM_RC_RXF0OVFL_REINIT);
-		wl_timer_mod(dhd, &apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT);
+		wl_ext_mod_timer(&apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT, 0);
 	}
 	else if ((cur_if->ifmode == IAP_MODE) &&
 			((etype == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) ||
@@ -5283,7 +4658,7 @@
 			reason == WLC_E_REASON_INITIAL_ASSOC))) {
 		// Link up
 		wl_ext_counters_update(cur_if, ISAM_RC_RXF0OVFL_REINIT);
-		wl_timer_mod(dhd, &apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT);
+		wl_ext_mod_timer(&apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT, 0);
 	}
 	else if ((etype == WLC_E_RESERVED) && (reason == ISAM_RC_RXF0OVFL_REINIT) &&
 			(wl_ext_iapsta_other_if_enabled(cur_if->dev))) {
@@ -5312,7 +4687,7 @@
 			wl_ext_ioctl(cur_if->dev, WLC_INIT, NULL, 0, 1);
 		}
 done:
-		wl_timer_mod(dhd, &apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT);
+		wl_ext_mod_timer(&apsta_params->rxf0ovfl_timer, RXF0OVFL_POLLING_TIMEOUT, 0);
 	}
 
 	return;
@@ -5320,15 +4695,36 @@
 #endif /* RXF0OVFL_REINIT_WAR */
 
 void
-wl_ext_iapsta_link(struct wl_if_info *cur_if,
+wl_ext_iapsta_event(struct net_device *dev, void *argu,
 	const wl_event_msg_t *e, void *data)
 {
-	struct dhd_pub *dhd = dhd_get_pub(cur_if->dev);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
+	struct wl_apsta_params *apsta_params = (struct wl_apsta_params *)argu;
+	struct wl_if_info *cur_if = NULL;
+#if defined(WLMESH) && defined(WL_ESCAN)
+	struct wl_if_info *tmp_if = NULL;
+	struct wl_if_info *mesh_if = NULL;
+	int i;
+#endif /* WLMESH && WL_ESCAN */
 	uint32 event_type = ntoh32(e->event_type);
 	uint32 status =  ntoh32(e->status);
 	uint32 reason =  ntoh32(e->reason);
 	uint16 flags =  ntoh16(e->flags);
+
+	cur_if = wl_get_cur_if(dev);
+
+#if defined(WLMESH) && defined(WL_ESCAN)
+	for (i=0; i<MAX_IF_NUM; i++) {
+		tmp_if = &apsta_params->if_info[i];
+		if (tmp_if->dev && tmp_if->ifmode == IMESH_MODE) {
+			mesh_if = tmp_if;
+			break;
+		}
+	}
+#endif /* WLMESH && WL_ESCAN */
+	if (!cur_if || !cur_if->dev) {
+		IAPSTA_DBG(dev->name, "ifidx %d is not ready\n", e->ifidx);
+		return;
+	}
 
 	if (cur_if->ifmode == ISTA_MODE || cur_if->ifmode == IGC_MODE) {
 		if (event_type == WLC_E_LINK) {
@@ -5341,6 +4737,10 @@
 				wl_ext_net_setcarrier(cur_if, FALSE, FALSE);
 #endif /* SET_CARRIER */
 				wl_clr_isam_status(cur_if, STA_CONNECTED);
+#if defined(WLMESH) && defined(WL_ESCAN)
+				if (mesh_if && apsta_params->macs)
+					wl_mesh_clear_mesh_info(apsta_params, mesh_if, TRUE);
+#endif /* WLMESH && WL_ESCAN */
 			} else {
 				WL_MSG(cur_if->ifname, "[%c] Link UP with %pM\n",
 					cur_if->prefix, &e->addr);
@@ -5348,11 +4748,15 @@
 				wl_ext_net_setcarrier(cur_if, TRUE, FALSE);
 #endif /* SET_CARRIER */
 				wl_set_isam_status(cur_if, STA_CONNECTED);
+#if defined(WLMESH) && defined(WL_ESCAN)
+				if (mesh_if && apsta_params->macs)
+					wl_mesh_update_master_info(apsta_params, mesh_if);
+#endif /* WLMESH && WL_ESCAN */
 			}
 			wl_clr_isam_status(cur_if, STA_CONNECTING);
 			wake_up_interruptible(&apsta_params->netif_change_event);
 #ifdef PROPTX_MAXCOUNT
-			wl_ext_update_wlfc_maxcount(dhd);
+			wl_ext_update_wlfc_maxcount(apsta_params->dhd);
 #endif /* PROPTX_MAXCOUNT */
 		}
 		else if (event_type == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) {
@@ -5361,8 +4765,12 @@
 				event_type, reason, status);
 			wl_clr_isam_status(cur_if, STA_CONNECTING);
 			wake_up_interruptible(&apsta_params->netif_change_event);
+#if defined(WLMESH) && defined(WL_ESCAN)
+			if (mesh_if && apsta_params->macs)
+				wl_mesh_clear_mesh_info(apsta_params, mesh_if, TRUE);
+#endif /* WLMESH && WL_ESCAN */
 #ifdef PROPTX_MAXCOUNT
-			wl_ext_update_wlfc_maxcount(dhd);
+			wl_ext_update_wlfc_maxcount(apsta_params->dhd);
 #endif /* PROPTX_MAXCOUNT */
 		}
 		else if (event_type == WLC_E_DEAUTH || event_type == WLC_E_DEAUTH_IND ||
@@ -5373,6 +4781,10 @@
 #ifdef SET_CARRIER
 			wl_ext_net_setcarrier(cur_if, FALSE, FALSE);
 #endif /* SET_CARRIER */
+#if defined(WLMESH) && defined(WL_ESCAN)
+			if (mesh_if && apsta_params->macs)
+				wl_mesh_clear_mesh_info(apsta_params, mesh_if, TRUE);
+#endif /* WLMESH && WL_ESCAN */
 		}
 	}
 	else if (cur_if->ifmode == IAP_MODE || cur_if->ifmode == IGO_MODE ||
@@ -5394,7 +4806,7 @@
 			wl_ext_net_setcarrier(cur_if, TRUE, FALSE);
 #endif /* SET_CARRIER */
 #ifdef PROPTX_MAXCOUNT
-			wl_ext_update_wlfc_maxcount(dhd);
+			wl_ext_update_wlfc_maxcount(apsta_params->dhd);
 #endif /* PROPTX_MAXCOUNT */
 		}
 		else if ((event_type == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS) ||
@@ -5407,7 +4819,7 @@
 			wl_ext_net_setcarrier(cur_if, FALSE, FALSE);
 #endif /* SET_CARRIER */
 #ifdef PROPTX_MAXCOUNT
-			wl_ext_update_wlfc_maxcount(dhd);
+			wl_ext_update_wlfc_maxcount(apsta_params->dhd);
 #endif /* PROPTX_MAXCOUNT */
 		}
 		else if ((event_type == WLC_E_ASSOC_IND || event_type == WLC_E_REASSOC_IND) &&
@@ -5425,34 +4837,17 @@
 				event_type, reason);
 			wl_ext_isam_status(cur_if->dev, NULL, 0);
 		}
-	}
-}
-
-void
-wl_ext_iapsta_event(struct net_device *dev, void *argu,
-	const wl_event_msg_t *e, void *data)
-{
-#ifdef ACS_MONITOR
-	struct wl_apsta_params *apsta_params = (struct wl_apsta_params *)argu;
-#endif /* ACS_MONITOR */
-	struct dhd_pub *dhd = dhd_get_pub(dev);
-	struct wl_if_info *cur_if = NULL;
-
-	cur_if = wl_get_cur_if(dev);
-	if (!cur_if || !cur_if->dev) {
-		IAPSTA_DBG(dev->name, "ifidx %d is not ready\n", e->ifidx);
-		return;
+#if defined(WLMESH) && defined(WL_ESCAN)
+		if (cur_if->ifmode == IMESH_MODE && apsta_params->macs)
+			wl_mesh_event_handler(apsta_params, cur_if, e, data);
+#endif /* WLMESH && WL_ESCAN */
 	}
 
-	wl_ext_iapsta_link(cur_if, e, data);
 #ifdef TPUT_MONITOR
-	if (dhd->conf->tput_monitor_ms)
-		wl_tput_monitor_handler(cur_if, e, data);
+	if (apsta_params->dhd->conf->tput_monitor_ms)
+		wl_tput_monitor_handler(apsta_params, cur_if, e, data);
 #endif /* TPUT_MONITOR */
 
-#if defined(WLMESH) && defined(WL_ESCAN)
-	wl_mesh_event_handler(cur_if, e, data);
-#endif /* WLMESH && WL_ESCAN */
 #ifdef ACS_MONITOR
 	if ((apsta_params->acs & ACS_DRV_BIT) && apsta_params->acs_tmo)
 		wl_acs_handler(cur_if, e, data);
@@ -5460,9 +4855,6 @@
 #ifdef EAPOL_RESEND
 	wl_resend_eapol_handler(cur_if, e, data);
 #endif /* EAPOL_RESEND */
-#ifdef KEY_INSTALL_CHECK
-	wl_ext_key_install_handler(cur_if, e, data);
-#endif /* KEY_INSTALL_CHECK */
 #ifdef RESTART_AP_WAR
 	wl_ext_restart_ap_handler(cur_if, e, data);
 #endif /* RESTART_AP_WAR */
@@ -5714,6 +5106,10 @@
 			cur_if->vsdb = FALSE;
 			cur_if->prefix = 'M';
 			snprintf(cur_if->ssid, DOT11_MAX_SSID_LEN, "ttt_mesh");
+#ifdef WL_ESCAN
+			if (i == 0 && apsta_params->macs)
+				wl_mesh_escan_attach(dhd, cur_if);
+#endif /* WL_ESCAN */
 #endif /* WLMESH */
 		}
 	}
@@ -5821,6 +5217,7 @@
 	}
 #endif /* WLMESH */
 
+	wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
 	apsta_params->init = TRUE;
 
 	WL_MSG(dev->name, "apstamode=%d\n", apstamode);
@@ -5978,7 +5375,6 @@
 				(chan_5g && cur_if->chan_info.band == WLC_BAND_5G)) {
 			cur_if->chan_info.chan = wl_ext_autochannel(cur_if->dev, apsta_params->acs,
 				cur_if->chan_info.band);
-			cur_if->chan_info.chan = wf_chspec_ctlchan(cur_if->chan_info.chan);
 		} else {
 			IAPSTA_ERROR(ifname, "invalid channel\n");
 			ret = -1;
@@ -5995,7 +5391,7 @@
 	}
 
 	memset(&chan_info, 0, sizeof(struct wl_chan_info));
-	wl_ext_get_chan(cur_if->dev, &chan_info);
+	wl_ext_get_chan(apsta_params, cur_if->dev, &chan_info);
 	if (chan_info.chan) {
 		IAPSTA_INFO(cur_if->ifname, "Associated\n");
 		if (!wl_ext_same_chan(&cur_if->chan_info, &chan_info)) {
@@ -6040,7 +5436,7 @@
 	}
 
 	wl_ext_set_amode(cur_if);
-	wl_ext_set_emode(cur_if);
+	wl_ext_set_emode(apsta_params, cur_if);
 
 	if (cur_if->ifmode == ISTA_MODE) {
 		conn_info.bssidx = cur_if->bssidx;
@@ -6171,6 +5567,8 @@
 wl_ext_isam_dev_status(struct net_device *dev, ifmode_t ifmode, char prefix,
 	char *dump_buf, int dump_len)
 {
+	struct dhd_pub *dhd = dhd_get_pub(dev);
+	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
 	struct wl_chan_info chan_info;
 	wlc_ssid_t ssid = { 0, {0} };
 	struct ether_addr bssid;
@@ -6187,8 +5585,9 @@
 		if (wl_ext_associated(dev)) {
 			wl_ext_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid), 0);
 			wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), 0);
-			wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t), 0);
-			chanspec = wl_ext_get_chanspec(dev, &chan_info);
+			wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
+				sizeof(scb_val_t), 0);
+			chanspec = wl_ext_get_chanspec(apsta_params, dev, &chan_info);
 			wl_ext_get_sec(dev, ifmode, sec, sizeof(sec), FALSE);
 			dump_written += snprintf(dump_buf+dump_written, dump_len,
 				"\n" DHD_LOG_PREFIXS "[%s-%c]: bssid=%pM, chan=%s-%-3d(0x%x %sMHz), "
@@ -6309,7 +5708,7 @@
 				if (apsta_params->acs_tmo != acs_tmo) {
 					apsta_params->acs_tmo = acs_tmo;
 					WL_MSG(dev->name, "acs_timer reset to %d\n", acs_tmo);
-					wl_timer_mod(dhd, &cur_if->acs_timer, 0);
+					wl_ext_mod_timer(&cur_if->acs_timer, acs_tmo, 0);
 				}
 				ret = 0;
 			} else {
@@ -6626,6 +6025,7 @@
 	}
 	// fix me: how to check it's ISTAAP_MODE or IDUALAP_MODE?
 
+	wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
 	WL_MSG(dev->name, "apstamode=%d\n", apsta_params->apstamode);
 
 	for (i=0; i<MAX_IF_NUM; i++) {
@@ -6696,28 +6096,6 @@
 }
 
 static void
-wl_ext_iapsta_get_mapsta_mode(struct net_device *net)
-{
-	struct dhd_pub *dhd = dhd_get_pub(net);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
-	int ret, mapsta_mode;
-
-	ret = wldev_iovar_getint(net, "mapsta_mode", &mapsta_mode);
-	if (ret) {
-		IAPSTA_INFO(net->name, "not supported %d\n", ret);
-		mapsta_mode = MCHAN_APSTA_NOT_ALLOW;
-	}
-
-	if (mapsta_mode == MCHAN_APSTA_SBSC)
-		apsta_params->rsdb = 1;
-	else if (mapsta_mode == MCHAN_APSTA_NO_RESTRICT)
-		apsta_params->vsdb = TRUE;
-
-	IAPSTA_INFO(net->name, "mapsta_mode=%d(rsdb=%d, vsdb=%d)\n",
-		mapsta_mode, apsta_params->rsdb, apsta_params->vsdb);
-}
-
-static void
 wl_ext_iapsta_postinit(struct net_device *net, struct wl_if_info *cur_if)
 {
 	struct dhd_pub *dhd = dhd_get_pub(net);
@@ -6728,17 +6106,12 @@
 	if (cur_if->ifidx == 0) {
 		apsta_params->rsdb = wl_ext_iapsta_get_rsdb(net, dhd);
 		apsta_params->vsdb = FALSE;
-		wl_ext_iapsta_get_mapsta_mode(net);
 		apsta_params->csa = 0;
 		apsta_params->acs = 0;
 		apsta_params->radar = wl_ext_radar_detect(net);
 		if (dhd->conf->fw_type == FW_TYPE_MESH) {
 			apsta_params->csa |= (CSA_FW_BIT | CSA_DRV_BIT);
 		}
-		cur_if->ifmode = ISTA_MODE;
-		cur_if->prio = PRIO_STA;
-		cur_if->vsdb = TRUE;
-		cur_if->prefix = 'S';
 		if (dhd->conf->vndr_ie_assocreq && strlen(dhd->conf->vndr_ie_assocreq))
 			wl_ext_add_del_ie(net, VNDR_IE_ASSOCREQ_FLAG, dhd->conf->vndr_ie_assocreq, "add");
 	} else {
@@ -6898,32 +6271,6 @@
 }
 #endif /* WLDWDS */
 
-static void
-wl_ext_iapsta_init_priv(struct net_device *net)
-{
-	struct dhd_pub *dhd = dhd_get_pub(net);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
-
-	init_waitqueue_head(&apsta_params->netif_change_event);
-	mutex_init(&apsta_params->usr_sync);
-	mutex_init(&apsta_params->in4way_sync);
-#ifdef STA_MGMT
-	INIT_LIST_HEAD(&apsta_params->sta_list);
-#endif /* STA_MGMT */
-#ifdef EAPOL_RESEND
-	spin_lock_init(&apsta_params->eapol_lock);
-#endif /* EAPOL_RESEND */
-}
-
-static void
-wl_ext_iapsta_deinit_priv(struct net_device *net)
-{
-	struct dhd_pub *dhd = dhd_get_pub(net);
-	struct wl_apsta_params *apsta_params = dhd->iapsta_params;
-
-	memset(apsta_params, 0, sizeof(struct wl_apsta_params));
-}
-
 int
 wl_ext_iapsta_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx)
 {
@@ -6935,52 +6282,87 @@
 		IAPSTA_TRACE(net->name, "ifidx=%d, bssidx=%d\n", ifidx, bssidx);
 		cur_if = &apsta_params->if_info[ifidx];
 	}
-
 	if (ifidx == 0) {
-		wl_ext_iapsta_init_priv(net);
-		strcpy(cur_if->ifname, net->name);
-#ifdef TPUT_MONITOR
-		wl_timer_register(net, &apsta_params->monitor_timer, wl_tput_monitor_timer);
-#endif /* TPUT_MONITOR */
-#ifdef RXF0OVFL_REINIT_WAR
-		wl_timer_register(net, &apsta_params->rxf0ovfl_timer, wl_ext_rxf0ovfl_reinit_timeout);
-#endif /* RXF0OVFL_REINIT_WAR */
-	}
-
-	if (ifidx == 0 || (cur_if && wl_get_isam_status(cur_if, IF_ADDING))) {
+		memset(apsta_params, 0, sizeof(struct wl_apsta_params));
+		apsta_params->dhd = dhd;
 		cur_if->dev = net;
 		cur_if->ifidx = ifidx;
 		cur_if->bssidx = bssidx;
+		cur_if->ifmode = ISTA_MODE;
+		cur_if->prio = PRIO_STA;
+		cur_if->vsdb = TRUE;
+		cur_if->prefix = 'S';
+		wl_ext_event_register(net, dhd, WLC_E_LAST, wl_ext_iapsta_event,
+			apsta_params, PRIO_EVENT_IAPSTA);
+		strcpy(cur_if->ifname, net->name);
+		init_waitqueue_head(&apsta_params->netif_change_event);
+		init_waitqueue_head(&apsta_params->ap_recon_sta_event);
+		mutex_init(&apsta_params->usr_sync);
+		mutex_init(&apsta_params->in4way_sync);
 		mutex_init(&cur_if->pm_sync);
+#ifdef STA_MGMT
+		INIT_LIST_HEAD(&apsta_params->sta_list);
+#endif /* STA_MGMT */
+#ifdef TPUT_MONITOR
+		init_timer_compat(&apsta_params->monitor_timer, wl_tput_monitor_timer, net);
+#endif /* TPUT_MONITOR */
+#ifdef ACS_MONITOR
+		wl_acs_attach(dhd, cur_if);
+#endif /* ACS_MONITOR */
 		INIT_DELAYED_WORK(&cur_if->pm_enable_work, wl_ext_pm_work_handler);
-		init_waitqueue_head(&cur_if->ap_recon_sta_event);
+#ifdef SET_CARRIER
+		wl_ext_net_setcarrier(cur_if, FALSE, TRUE);
+#endif /* SET_CARRIER */
+		init_timer_compat(&cur_if->connect_timer, wl_ext_connect_timeout, net);
+#if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
+		init_timer_compat(&cur_if->reconnect_timer, wl_ext_reconnect_timeout, net);
+#endif /* WL_EXT_RECONNECT && WL_CFG80211 */
+#ifdef RESTART_AP_WAR
+		init_timer_compat(&cur_if->restart_ap_timer, wl_ext_restart_ap_timeout, net);
+#endif /* RESTART_AP_WAR */
+#ifdef RESET_AP_WAR
+		init_timer_compat(&cur_if->reset_ap_timer, wl_ext_reset_ap_timeout, net);
+#endif /* RESET_AP_WAR */
+#ifdef RXF0OVFL_REINIT_WAR
+		init_timer_compat(&apsta_params->rxf0ovfl_timer, wl_ext_rxf0ovfl_reinit_timeout, net);
+#endif /* RXF0OVFL_REINIT_WAR */
+#ifdef EAPOL_RESEND
+		spin_lock_init(&apsta_params->eapol_lock);
+		init_timer_compat(&cur_if->eapol_timer, wl_eapol_timer, net);
+#endif /* EAPOL_RESEND */
+	}
+	else if (cur_if && wl_get_isam_status(cur_if, IF_ADDING)) {
+		cur_if->dev = net;
+		cur_if->ifidx = ifidx;
+		cur_if->bssidx = bssidx;
 		wl_ext_event_register(net, dhd, WLC_E_LAST, wl_ext_iapsta_event,
 			apsta_params, PRIO_EVENT_IAPSTA);
 #if defined(WLMESH) && defined(WL_ESCAN)
-		wl_mesh_escan_attach(dhd, cur_if);
+		if (cur_if->ifmode == IMESH_MODE && apsta_params->macs) {
+			wl_mesh_escan_attach(dhd, cur_if);
+		}
 #endif /* WLMESH && WL_ESCAN */
 #ifdef ACS_MONITOR
 		wl_acs_attach(dhd, cur_if);
 #endif /* ACS_MONITOR */
+		mutex_init(&cur_if->pm_sync);
+		INIT_DELAYED_WORK(&cur_if->pm_enable_work, wl_ext_pm_work_handler);
 #ifdef SET_CARRIER
 		wl_ext_net_setcarrier(cur_if, FALSE, TRUE);
 #endif /* SET_CARRIER */
-		wl_timer_register(net, &cur_if->connect_timer, wl_ext_connect_timeout);
-#if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
-		wl_timer_register(net, &cur_if->reconnect_timer, wl_ext_reconnect_timeout);
-#endif /* WL_EXT_RECONNECT && WL_CFG80211 */
+		init_timer_compat(&cur_if->connect_timer, wl_ext_connect_timeout, net);
 #ifdef RESTART_AP_WAR
-		wl_timer_register(net, &cur_if->restart_ap_timer, wl_ext_restart_ap_timeout);
+		init_timer_compat(&cur_if->restart_ap_timer, wl_ext_restart_ap_timeout, net);
 #endif /* RESTART_AP_WAR */
 #ifdef RESET_AP_WAR
-		wl_timer_register(net, &cur_if->reset_ap_timer, wl_ext_reset_ap_timeout);
+		init_timer_compat(&cur_if->reset_ap_timer, wl_ext_reset_ap_timeout, net);
 #endif /* RESET_AP_WAR */
+#if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
+		init_timer_compat(&cur_if->reconnect_timer, wl_ext_reconnect_timeout, net);
+#endif /* WL_EXT_RECONNECT && WL_CFG80211 */
 #ifdef EAPOL_RESEND
-		wl_timer_register(net, &cur_if->eapol_timer, wl_eapol_timer);
+		init_timer_compat(&cur_if->eapol_timer, wl_eapol_timer, net);
 #endif /* EAPOL_RESEND */
-#ifdef KEY_INSTALL_CHECK
-		wl_timer_register(net, &cur_if->key_install_timer, wl_ext_key_install_timeout);
-#endif /* KEY_INSTALL_CHECK */
 	}
 
 	return 0;
@@ -7001,23 +6383,58 @@
 		cur_if = &apsta_params->if_info[ifidx];
 	}
 
-	if (ifidx == 0 || (cur_if && (wl_get_isam_status(cur_if, IF_READY) ||
-			wl_get_isam_status(cur_if, IF_ADDING)))) {
+	if (ifidx == 0) {
 #ifdef EAPOL_RESEND
 		wl_ext_release_eapol_txpkt(dhd, ifidx, FALSE);
 #endif /* EAPOL_RESEND */
-#ifdef KEY_INSTALL_CHECK
-		wl_timer_deregister(net, &cur_if->key_install_timer);
-#endif /* KEY_INSTALL_CHECK */
-		wl_timer_deregister(net, &cur_if->connect_timer);
+		wl_ext_mod_timer(&cur_if->connect_timer, 0, 0);
 #if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
-		wl_timer_deregister(net, &cur_if->reconnect_timer);
+		wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0);
 #endif /* WL_EXT_RECONNECT && WL_CFG80211 */
 #ifdef RESTART_AP_WAR
-		wl_timer_deregister(net, &cur_if->restart_ap_timer);
+		wl_ext_mod_timer(&cur_if->restart_ap_timer, 0, 0);
 #endif /* RESTART_AP_WAR */
 #ifdef RESET_AP_WAR
-		wl_timer_deregister(net, &cur_if->reset_ap_timer);
+		wl_ext_mod_timer(&cur_if->reset_ap_timer, 0, 0);
+#endif /* RESET_AP_WAR */
+#ifdef RXF0OVFL_REINIT_WAR
+		wl_ext_mod_timer(&apsta_params->rxf0ovfl_timer, 0, 0);
+#endif /* RXF0OVFL_REINIT_WAR */
+#ifdef SET_CARRIER
+		wl_ext_net_setcarrier(cur_if, FALSE, FALSE);
+#endif /* SET_CARRIER */
+		wl_ext_add_remove_pm_enable_work(net, FALSE);
+#ifdef ACS_MONITOR
+		wl_acs_detach(cur_if);
+#endif /* ACS_MONITOR */
+#ifdef TPUT_MONITOR
+		wl_ext_mod_timer(&apsta_params->monitor_timer, 0, 0);
+#endif /* TPUT_MONITOR */
+#if defined(WLMESH) && defined(WL_ESCAN)
+		if (cur_if->ifmode == IMESH_MODE && apsta_params->macs) {
+			wl_mesh_escan_detach(dhd, cur_if);
+		}
+#endif /* WLMESH && WL_ESCAN */
+		wl_ext_event_deregister(net, dhd, WLC_E_LAST, wl_ext_iapsta_event);
+#ifdef STA_MGMT
+		wl_ext_flush_sta_list(net, ifidx);
+#endif /* STA_MGMT */
+		memset(apsta_params, 0, sizeof(struct wl_apsta_params));
+	}
+	else if (cur_if && (wl_get_isam_status(cur_if, IF_READY) ||
+			wl_get_isam_status(cur_if, IF_ADDING))) {
+#ifdef EAPOL_RESEND
+		wl_ext_release_eapol_txpkt(dhd, ifidx, FALSE);
+#endif /* EAPOL_RESEND */
+		wl_ext_mod_timer(&cur_if->connect_timer, 0, 0);
+#if defined(WL_EXT_RECONNECT) && defined(WL_CFG80211)
+		wl_ext_mod_timer(&cur_if->reconnect_timer, 0, 0);
+#endif /* WL_EXT_RECONNECT && WL_CFG80211 */
+#ifdef RESTART_AP_WAR
+		wl_ext_mod_timer(&cur_if->restart_ap_timer, 0, 0);
+#endif /* RESTART_AP_WAR */
+#ifdef RESET_AP_WAR
+		wl_ext_mod_timer(&cur_if->reset_ap_timer, 0, 0);
 #endif /* RESET_AP_WAR */
 #ifdef SET_CARRIER
 		wl_ext_net_setcarrier(cur_if, FALSE, FALSE);
@@ -7027,7 +6444,9 @@
 		wl_acs_detach(cur_if);
 #endif /* ACS_MONITOR */
 #if defined(WLMESH) && defined(WL_ESCAN)
-		wl_mesh_escan_detach(dhd, cur_if);
+		if (cur_if->ifmode == IMESH_MODE && apsta_params->macs) {
+			wl_mesh_escan_detach(dhd, cur_if);
+		}
 #endif /* WLMESH && WL_ESCAN */
 		wl_ext_event_deregister(net, dhd, WLC_E_LAST, wl_ext_iapsta_event);
 #ifdef STA_MGMT
@@ -7036,15 +6455,23 @@
 		memset(cur_if, 0, sizeof(struct wl_if_info));
 	}
 
-	if (ifidx == 0) {
-#ifdef RXF0OVFL_REINIT_WAR
-		wl_timer_deregister(net, &apsta_params->rxf0ovfl_timer);
-#endif /* RXF0OVFL_REINIT_WAR */
-#ifdef TPUT_MONITOR
-		wl_timer_deregister(net, &apsta_params->monitor_timer);
-#endif /* TPUT_MONITOR */
-		wl_ext_iapsta_deinit_priv(net);
+	return 0;
+}
+
+int
+wl_ext_iapsta_attach(struct net_device *net)
+{
+	struct dhd_pub *dhd = dhd_get_pub(net);
+	struct wl_apsta_params *iapsta_params;
+
+	IAPSTA_TRACE(net->name, "Enter\n");
+
+	iapsta_params = kzalloc(sizeof(struct wl_apsta_params), GFP_KERNEL);
+	if (unlikely(!iapsta_params)) {
+		IAPSTA_ERROR("wlan", "Could not allocate apsta_params\n");
+		return -ENOMEM;
 	}
+	dhd->iapsta_params = (void *)iapsta_params;
 
 	return 0;
 }
@@ -7056,47 +6483,9 @@
 
 	IAPSTA_TRACE(net->name, "Enter\n");
 
-	if (g_ioctl_buf) {
-		kfree(g_ioctl_buf);
-		g_ioctl_buf = NULL;
-	}
-
 	if (dhd->iapsta_params) {
-		wl_ext_iapsta_deinit_priv(net);
 		kfree(dhd->iapsta_params);
 		dhd->iapsta_params = NULL;
 	}
-}
-
-int
-wl_ext_iapsta_attach(struct net_device *net)
-{
-	struct dhd_pub *dhd = dhd_get_pub(net);
-	struct wl_apsta_params *iapsta_params;
-	int ret = 0;
-
-	IAPSTA_TRACE(net->name, "Enter\n");
-
-	iapsta_params = kzalloc(sizeof(struct wl_apsta_params), GFP_KERNEL);
-	if (unlikely(!iapsta_params)) {
-		IAPSTA_ERROR(net->name, "Can not allocate apsta_params\n");
-		ret = -ENOMEM;
-		goto exit;
-	}
-	dhd->iapsta_params = (void *)iapsta_params;
-
-	if (!g_ioctl_buf) {
-		g_ioctl_buf = kmalloc(WL_DUMP_BUF_LEN, GFP_KERNEL);
-		if (unlikely(!g_ioctl_buf)) {
-			IAPSTA_ERROR(net->name, "Can not allocate g_ioctl_buf\n");
-			ret = -ENOMEM;
-			goto exit;
-		}
-	}
-
-exit:
-	if (ret)
-		wl_ext_iapsta_dettach(net);
-	return ret;
 }
 #endif /* WL_EXT_IAPSTA */

--
Gitblit v1.6.2