bcm4329: Fix AP interface processing and removal, Improve BT-coex during DHCP session

Change-Id: Iba120a2bb21582aeef72a06a99d7f19b62d2df75
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/bcm4329/src/bcmsdio/sys/bcmsdh.c b/bcm4329/src/bcmsdio/sys/bcmsdh.c
index c9906e2..aed6859 100644
--- a/bcm4329/src/bcmsdio/sys/bcmsdh.c
+++ b/bcm4329/src/bcmsdio/sys/bcmsdh.c
@@ -2,7 +2,7 @@
  *  BCMSDH interface glue
  *  implement bcmsdh API for SDIOH driver
  *
- * Copyright (C) 1999-2009, Broadcom Corporation
+ * Copyright (C) 1999-2010, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -22,7 +22,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: bcmsdh.c,v 1.35.2.1.4.8.6.11 2009/10/20 09:48:20 Exp $
+ * $Id: bcmsdh.c,v 1.35.2.1.4.8.6.13 2010/04/06 03:26:57 Exp $
  */
 /* ****************** BCMSDH Interface Functions *************************** */
 
@@ -59,7 +59,6 @@
 bcmsdh_info_t * l_bcmsdh = NULL;
 
 #if defined(OOB_INTR_ONLY) && defined(HW_OOB)
-
 extern int
 sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
 
@@ -68,7 +67,6 @@
 {
 	sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
 }
-
 #endif
 
 bcmsdh_info_t *
diff --git a/bcm4329/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c b/bcm4329/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
index 871e8a9..196ad4f 100644
--- a/bcm4329/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
+++ b/bcm4329/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: bcmsdh_sdmmc_linux.c,v 1.1.2.5.6.11 2009/11/04 20:36:52 Exp $
+ * $Id: bcmsdh_sdmmc_linux.c,v 1.1.2.5.6.15 2010/04/14 21:11:46 Exp $
  */
 
 #include <typedefs.h>
@@ -75,7 +75,6 @@
 extern int bcmsdh_remove(struct device *dev);
 struct device sdmmc_dev;
 
-
 static int bcmsdh_sdmmc_probe(struct sdio_func *func,
                               const struct sdio_device_id *id)
 {
@@ -126,7 +125,6 @@
 static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) },
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) },
-	{ SDIO_DEVICE_CLASS(SDIO_CLASS_NONE)		},
 	{ /* end: all zeroes */				},
 };
 
diff --git a/bcm4329/src/dhd/sys/dhd.h b/bcm4329/src/dhd/sys/dhd.h
index 231fe56..3b22eb7 100644
--- a/bcm4329/src/dhd/sys/dhd.h
+++ b/bcm4329/src/dhd/sys/dhd.h
@@ -81,6 +81,9 @@
 	WAKE_LOCK_TMOUT,
 	WAKE_LOCK_WATCHDOG,
 	WAKE_LOCK_LINK_DOWN_TMOUT,
+	WAKE_LOCK_SOFTAP_SET,
+	WAKE_LOCK_SOFTAP_STOP,
+	WAKE_LOCK_SOFTAP_START,
 	WAKE_LOCK_MAX
 };
 enum dhd_prealloc_index {
@@ -325,10 +328,6 @@
 extern uint dhd_watchdog_ms;
 
 
-#if defined(DHD_DEBUG)
-extern uint wl_msg_level;
-#endif /* DHD_DEBUG */
-
 /* Use interrupts */
 extern uint dhd_intr;
 
diff --git a/bcm4329/src/dhd/sys/dhd_common.c b/bcm4329/src/dhd/sys/dhd_common.c
index 9dc7113..a0e6a73 100644
--- a/bcm4329/src/dhd/sys/dhd_common.c
+++ b/bcm4329/src/dhd/sys/dhd_common.c
@@ -90,7 +90,6 @@
 	{NULL, 0, 0, 0, 0 }
 };
 
-
 void
 dhd_common_init(void)
 {
diff --git a/bcm4329/src/dhd/sys/dhd_linux.c b/bcm4329/src/dhd/sys/dhd_linux.c
index 33ef2a9..c25a9b7 100644
--- a/bcm4329/src/dhd/sys/dhd_linux.c
+++ b/bcm4329/src/dhd/sys/dhd_linux.c
@@ -2176,15 +2176,16 @@
 			/* Attach and link in the iw */
 			wl_iw_detach();
 #endif
-			if (dhd->sysioc_pid >= 0) {
-				KILL_PROC(dhd->sysioc_pid, SIGTERM);
-				wait_for_completion(&dhd->sysioc_exited);
-			}
 
 			for (i = 1; i < DHD_MAX_IFS; i++)
 				if (dhd->iflist[i])
 					dhd_del_if(dhd, i);
 
+			if (dhd->sysioc_pid >= 0) {
+				KILL_PROC(dhd->sysioc_pid, SIGTERM);
+				wait_for_completion(&dhd->sysioc_exited);
+			}
+
 			ifp = dhd->iflist[0];
 			ASSERT(ifp);
 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
diff --git a/bcm4329/src/dhd/sys/dhd_sdio.c b/bcm4329/src/dhd/sys/dhd_sdio.c
index d9aca24..8cb567f 100644
--- a/bcm4329/src/dhd/sys/dhd_sdio.c
+++ b/bcm4329/src/dhd/sys/dhd_sdio.c
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_sdio.c,v 1.157.2.27.2.33.2.102 2010/03/30 02:22:02 Exp $
+ * $Id: dhd_sdio.c,v 1.157.2.27.2.33.2.109 2010/04/22 05:52:46 Exp $
  */
 
 #include <typedefs.h>
@@ -1047,6 +1047,8 @@
 	if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq) || bus->dpc_sched ||
 	    (!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) ||
 	    (bus->clkstate == CLK_PENDING)) {
+		DHD_TRACE(("%s: deferring pktq len %d\n", __FUNCTION__,
+			pktq_len(&bus->txq)));
 		bus->fcqueued++;
 
 		/* Priority based enq */
@@ -1055,10 +1057,11 @@
 			PKTPULL(osh, pkt, SDPCM_HDRLEN);
 			dhd_txcomplete(bus->dhd, pkt, FALSE);
 			PKTFREE(osh, pkt, TRUE);
+			DHD_ERROR(("%s: out of bus->txq !!!\n", __FUNCTION__));
 			ret = BCME_NORESOURCE;
-		}
-		else
+		} else {
 			ret = BCME_OK;
+		}
 		dhd_os_sdunlock_txq(bus->dhd);
 
 		if ((pktq_len(&bus->txq) >= FCHI) && dhd_doflow)
@@ -1082,6 +1085,7 @@
 		dhdsdio_clkctl(bus, CLK_AVAIL, TRUE);
 
 #ifndef SDTEST
+		DHD_TRACE(("%s: calling txpkt\n", __FUNCTION__));
 		ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE);
 #else
 		ret = dhdsdio_txpkt(bus, pkt,
diff --git a/bcm4329/src/include/epivers.h b/bcm4329/src/include/epivers.h
index 20f5e47..3ab7ad7 100644
--- a/bcm4329/src/include/epivers.h
+++ b/bcm4329/src/include/epivers.h
@@ -31,18 +31,18 @@
 
 #define	EPI_MINOR_VERSION	218
 
-#define	EPI_RC_NUMBER		209
+#define	EPI_RC_NUMBER		223
 
 #define	EPI_INCREMENTAL_NUMBER	0
 
 #define	EPI_BUILD_NUMBER	0
 
-#define	EPI_VERSION		4, 218, 209, 0
+#define	EPI_VERSION		4, 218, 223, 0
 
-#define	EPI_VERSION_NUM		0x04dad100
+#define	EPI_VERSION_NUM		0x04dadf00
 
 
-#define	EPI_VERSION_STR		"4.218.209.0"
-#define	EPI_ROUTER_VERSION_STR	"4.219.209.0"
+#define	EPI_VERSION_STR		"4.218.223.0"
+#define	EPI_ROUTER_VERSION_STR	"4.219.223.0"
 
 #endif 
diff --git a/bcm4329/src/include/wlioctl.h b/bcm4329/src/include/wlioctl.h
index 6923555..58a2f6c 100644
--- a/bcm4329/src/include/wlioctl.h
+++ b/bcm4329/src/include/wlioctl.h
@@ -24,7 +24,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: wlioctl.h,v 1.601.4.15.2.14.2.59 2010/02/09 13:23:22 Exp $
+ * $Id: wlioctl.h,v 1.601.4.15.2.14.2.60 2010/04/12 05:33:02 Exp $
  */
 
 
@@ -1324,12 +1324,12 @@
 } wl_pfn_param_t;
 
 typedef struct wl_pfn {
-	wlc_ssid_t		ssid;			
-	int32			bss_type;		
-	int32			infra;			
-	int32			auth;			
-	int32			wpa_auth;		
-	int32			wsec;			
+	wlc_ssid_t		ssid;
+	int32			bss_type;
+	int32			infra;
+	int32			auth;
+	uint32			wpa_auth;
+	int32			wsec;
 #ifdef WLPFN_AUTO_CONNECT
 	union {
 		wl_wsec_key_t	sec_key;		
diff --git a/bcm4329/src/wl/sys/wl_iw.c b/bcm4329/src/wl/sys/wl_iw.c
index cf6bf80..de32e94 100644
--- a/bcm4329/src/wl/sys/wl_iw.c
+++ b/bcm4329/src/wl/sys/wl_iw.c
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: wl_iw.c,v 1.51.4.9.2.6.4.90 2010/03/31 18:03:04 Exp $
+ * $Id: wl_iw.c,v 1.51.4.9.2.6.4.104 2010/04/21 23:21:00 Exp $
  */
 
 
@@ -70,10 +70,10 @@
 static struct net_device *priv_dev;
 static bool ap_cfg_running = FALSE;
 static bool ap_fw_loaded = FALSE;
-static int ap_mode = 0;
 struct net_device *ap_net_dev = NULL;
 struct semaphore  ap_eth_sema;
 static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap);
+static int wl_iw_softap_deassoc_stations(struct net_device *dev);
 #endif
 
 #define WL_IW_IOCTL_CALL(func_call) \
@@ -91,6 +91,7 @@
 extern void dhd_customer_gpio_wlan_ctrl(int onoff);
 extern uint dhd_dev_reset(struct net_device *dev, uint8 flag);
 extern void dhd_dev_init_ioctl(struct net_device *dev);
+int dev_iw_write_cfg1_bss_var(struct net_device *dev, int val);
 
 uint wl_msg_level = WL_ERROR_VAL;
 
@@ -152,6 +153,7 @@
 static void wl_iw_free_ss_cache(void);
 static int   wl_iw_run_ss_cache_timer(int kick_off);
 int  wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag);
+static int dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len);
 #define ISCAN_STATE_IDLE   0
 #define ISCAN_STATE_SCANING 1
 
@@ -338,6 +340,21 @@
 }
 
 
+static int
+dev_wlc_intvar_set_reg(
+	struct net_device *dev,
+	char *name,
+	char *addr,
+	char * val)
+{
+	char reg_addr[8];
+
+	memset(reg_addr, 0, sizeof(reg_addr));
+	memcpy((char *)&reg_addr[0], (char *)addr, 4);
+	memcpy((char *)&reg_addr[4], (char *)val, 4);
+
+	return (dev_wlc_bufvar_set(dev, name,  (char *)&reg_addr[0], sizeof(reg_addr)));
+}
 
 
 static int
@@ -564,7 +581,7 @@
 
 	
 	if (country_offset != 0) {
-		strncpy(country_code, extra + country_offset +1,
+		strncpy(country_code, extra + country_offset + 1,
 			MIN(country_code_size, sizeof(country_code)));
 
 		
@@ -584,6 +601,48 @@
 	return error;
 }
 
+#ifdef CUSTOMER_HW2
+static int
+wl_iw_set_power_mode(
+	struct net_device *dev,
+	struct iw_request_info *info,
+	union iwreq_data *wrqu,
+	char *extra
+)
+{
+	int error = 0;
+	char *p = extra;
+	static int pm = PM_FAST;
+	int pm_local = PM_OFF;
+	char powermode_val = 0;
+
+	strncpy((char *)&powermode_val, extra + strlen("POWERMODE") + 1, 1);
+
+	if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
+
+		WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__));
+
+		dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm));
+		dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local));
+	}
+	else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) {
+
+		WL_TRACE(("%s: DHCP session done\n", __FUNCTION__));
+
+		dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+	}
+	else {
+		WL_TRACE(("Unkwown yet power setting, ignored\n"));
+	}
+
+	p += snprintf(p, MAX_WX_STRING, "OK");
+
+	wrqu->data.length = p - extra + 1;
+
+	return error;
+}
+#endif
+
 static int
 wl_iw_set_btcoex_dhcp(
 	struct net_device *dev,
@@ -594,82 +653,109 @@
 {
 	int error = 0;
 	char *p = extra;
-	uint val;
-#ifdef  CUSTOMER_HW2
+#ifndef CUSTOMER_HW2
 	static int  pm = PM_FAST;
 	int  pm_local = PM_OFF;
-#endif	
+#endif
 	char powermode_val = 0;
 	char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 };
 	char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 };
 	char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 };
 
-	char buf_reg66val_defualt[8] = { 66, 00, 00, 00, 0x88, 0x13, 0x00, 0x00 };
-	char buf_reg41val_defualt[8] = { 41, 00, 00, 00, 0x13, 0x00, 0x00, 0x00 };
-	char buf_reg68val_defualt[8] = { 68, 00, 00, 00, 0x14, 0x00, 0x00, 0x00 };
+	uint32 regaddr;
+	static uint32 saved_reg66;
+	static uint32 saved_reg41;
+	static uint32 saved_reg68;
+	static bool saved_status = FALSE;
 
 	char buf_flag7_default[8] =   { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
+#ifndef CUSTOMER_HW2
+	uint32 temp1, temp2;
+#endif
 
-	
-	strncpy((char *)&powermode_val, extra + strlen("POWERMODE") +1, 1);
-
-	
-	dev_wlc_intvar_get_reg(dev, "btc_params", 68,  &val);
+#ifdef CUSTOMER_HW2
+	strncpy((char *)&powermode_val, extra + strlen("BTCOEXMODE") + 1, 1);
+#else
+	strncpy((char *)&powermode_val, extra + strlen("POWERMODE") + 1, 1);
+#endif
 
 	if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
 
 		WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__));
 
-#ifdef  CUSTOMER_HW2
-		
-		dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm));
-		
-		dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local));
-#endif 
+		if ((saved_status == FALSE) &&
+#ifndef CUSTOMER_HW2
+			(!dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))) &&
+#endif
+			(!dev_wlc_intvar_get_reg(dev, "btc_params", 66,  &saved_reg66)) &&
+			(!dev_wlc_intvar_get_reg(dev, "btc_params", 41,  &saved_reg41)) &&
+			(!dev_wlc_intvar_get_reg(dev, "btc_params", 68,  &saved_reg68)))   {
+				saved_status = TRUE;
+				WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", \
+					saved_reg66, saved_reg41, saved_reg68));
+
+#ifndef CUSTOMER_HW2
+				dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local));
+#endif
+
 		dev_wlc_bufvar_set(dev, "btc_params", \
 				   (char *)&buf_reg66va_dhcp_on[0], sizeof(buf_reg66va_dhcp_on));
-		
 		dev_wlc_bufvar_set(dev, "btc_params", \
 				   (char *)&buf_reg41va_dhcp_on[0], sizeof(buf_reg41va_dhcp_on));
-		
 		dev_wlc_bufvar_set(dev, "btc_params", \
 				   (char *)&buf_reg68va_dhcp_on[0], sizeof(buf_reg68va_dhcp_on));
-
-		
-		g_bt->bt_state = BT_DHCP_START;
-		g_bt->timer_on = 1;
-		mod_timer(&g_bt->timer, g_bt->timer.expires);
-		WL_TRACE(("%s enable BT DHCP Timer\n", __FUNCTION__));
-
+#ifndef CUSTOMER_HW2
+				if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 12, &temp1)) &&
+					(!dev_wlc_intvar_get_reg(dev, "btc_params", 13, &temp2)))
+				{
+					if ((temp1 != 0) && (temp2 != 0)) {
+#endif
+						g_bt->bt_state = BT_DHCP_START;
+						g_bt->timer_on = 1;
+						mod_timer(&g_bt->timer, g_bt->timer.expires);
+						WL_TRACE(("%s enable BT DHCP Timer\n", \
+							__FUNCTION__));
+#ifndef CUSTOMER_HW2
+					}
+				}
+#endif
+		}
+		else if (saved_status == TRUE) {
+			WL_ERROR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__));
+		}
 	}
+#ifdef CUSTOMER_HW2
+	else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) {
+#else
 	else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) {
-
+#endif
 		WL_TRACE(("%s: DHCP session done\n", __FUNCTION__));
 
-#ifdef  CUSTOMER_HW2
-		
+#ifndef CUSTOMER_HW2
 		dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
-#endif 
-		
+#endif
+
 		WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__));
 		if (g_bt->timer_on) {
 			g_bt->timer_on = 0;
 			del_timer_sync(&g_bt->timer);
 		}
 
-		
 		dev_wlc_bufvar_set(dev, "btc_flags", \
 				(char *)&buf_flag7_default[0], sizeof(buf_flag7_default));
 
-		
-		dev_wlc_bufvar_set(dev, "btc_params", \
-				   (char *)&buf_reg66val_defualt[0], sizeof(buf_reg66val_defualt));
-		
-		dev_wlc_bufvar_set(dev, "btc_params", \
-				   (char *)&buf_reg41val_defualt[0], sizeof(buf_reg41val_defualt));
-		
-		dev_wlc_bufvar_set(dev, "btc_params", \
-				   (char *)&buf_reg68val_defualt[0], sizeof(buf_reg68val_defualt));
+		if (saved_status) {
+			regaddr = 66;
+			dev_wlc_intvar_set_reg(dev, "btc_params", \
+				(char *)&regaddr, (char *)&saved_reg66);
+			regaddr = 41;
+			dev_wlc_intvar_set_reg(dev, "btc_params", \
+				(char *)&regaddr, (char *)&saved_reg41);
+			regaddr = 68;
+			dev_wlc_intvar_set_reg(dev, "btc_params", \
+				(char *)&regaddr, (char *)&saved_reg68);
+		}
+		saved_status = FALSE;
 	}
 	else {
 		WL_ERROR(("Unkwown yet power setting, ignored\n"));
@@ -792,59 +878,6 @@
 	return 0;
 }
 
-#ifdef WL_IW_USE_THREAD_WL_OFF
-static int
-_wl_control_sysioc_thread_wl_off(void *data)
-{
-	struct wl_ctrl *wl_ctl = (struct wl_ctrl *)data;
-
-	DAEMONIZE("wlcontrol_sysioc");
-
-	WL_TRACE(("%s Entered\n", __FUNCTION__));
-	net_os_wake_lock(wl_ctl->dev);
-
-	mutex_lock(&wl_start_lock);
-	while (down_interruptible(&wl_ctl->timer_sem) == 0) {
-
-		WL_TRACE(("%s Turning off wifi dev\n", __FUNCTION__));
-
-		g_onoff = G_WLAN_SET_OFF;
-
-#if defined(WL_IW_USE_ISCAN)
-		g_iscan->iscan_state = ISCAN_STATE_IDLE;
-#endif
-
-		dhd_dev_reset(wl_ctl->dev, 1);
-
-#if defined(WL_IW_USE_ISCAN)
-		wl_iw_free_ss_cache();
-		wl_iw_run_ss_cache_timer(0);
-		memset(g_scan, 0, G_SCAN_RESULTS);
-
-		g_ss_cache_ctrl.m_link_down = 1;
-		g_scan_specified_ssid = 0;
-
-		g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE;
-#endif
-#if defined(BCMLXSDMMC)
-		sdioh_stop(NULL);
-#endif
-
-		dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
-
-		wl_iw_send_priv_event(wl_ctl->dev, "STOP");
-
-		net_os_wake_lock_timeout_enable(wl_ctl->dev);
-		break;
-	}
-	mutex_unlock(&wl_start_lock);
-	WL_TRACE(("%s Exited\n", __FUNCTION__));
-	net_os_wake_unlock(wl_ctl->dev);
-
-	complete_and_exit(&wl_ctl->sysioc_exited, 0);
-	KILL_PROC(wl_ctl->sysioc_pid, SIGTERM);
-}
-#endif
 
 int
 wl_control_wl_start(struct net_device *dev)
@@ -853,7 +886,13 @@
 
 	WL_TRACE(("Enter %s \n", __FUNCTION__));
 
+	if (!dev) {
+		WL_ERROR(("%s: dev is null\n", __FUNCTION__));
+		return -1;
+	}
+
 	mutex_lock(&wl_start_lock);
+
 	if (g_onoff == G_WLAN_SET_OFF) {
 		dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
 
@@ -877,19 +916,6 @@
 	return ret;
 }
 
-#ifdef WL_IW_USE_THREAD_WL_OFF
-static void
-wl_iw_stop_timerfunc(ulong data)
-{
-	struct wl_ctrl * wl_ctl = (struct wl_ctrl *)data;
-
-	WL_TRACE(("%s\n", __FUNCTION__));
-
-	del_timer_sync(wl_ctl->timer);
-
-	up(&wl_ctl->timer_sem);
-}
-#endif
 
 static int
 wl_iw_control_wl_off(
@@ -898,32 +924,19 @@
 )
 {
 	int ret = 0;
-#ifdef WL_IW_USE_THREAD_WL_OFF
-	static struct wl_ctrl ctl;
-	static struct timer_list timer;
-#endif
 	WL_TRACE(("Enter %s\n", __FUNCTION__));
 
+	if (!dev) {
+		WL_ERROR(("%s: dev is null\n", __FUNCTION__));
+		return -1;
+	}
+
+	mutex_lock(&wl_start_lock);
+
 #ifdef SOFTAP
-	ap_mode = 0;
 	ap_cfg_running = FALSE;
 #endif
 
-#ifdef WL_IW_USE_THREAD_WL_OFF
-	ctl.timer = &timer;
-	ctl.dev = dev;
-	sema_init(&ctl.timer_sem, 0);
-	init_completion(&ctl.sysioc_exited);
-
-	ctl.sysioc_pid = kernel_thread(_wl_control_sysioc_thread_wl_off, &ctl, 0);
-
-	timer.data = (ulong)&ctl;
-	timer.function = wl_iw_stop_timerfunc;
-	init_timer(&timer);
-	timer.expires = jiffies + 2000 * HZ / 1000;
-	add_timer(&timer);
-#else
-	mutex_lock(&wl_start_lock);
 	if (g_onoff == G_WLAN_SET_ON) {
 		g_onoff = G_WLAN_SET_OFF;
 #if defined(WL_IW_USE_ISCAN)
@@ -953,8 +966,9 @@
 
 		net_os_wake_lock_timeout_enable(dev);
 	}
+
 	mutex_unlock(&wl_start_lock);
-#endif
+
 	WL_TRACE(("Exited %s\n", __FUNCTION__));
 
 	return ret;
@@ -1117,15 +1131,20 @@
 
 		str_ptr = extra;
 
-		init_ap_profile_from_string(extra, ap_cfg);
+		if ((res = init_ap_profile_from_string(extra, ap_cfg)) < 0) {
+			WL_ERROR(("%s failed to parse %d\n", __FUNCTION__, res));
+			kfree(extra);
+			return -1;
+		}
 
 	} else {
 		WL_ERROR(("IWPRIV argument len = 0 \n"));
 		return -1;
 	}
 
+	if ((res = set_ap_cfg(dev, ap_cfg)) < 0)
+		WL_ERROR(("%s failed to set_ap_cfg %d\n", __FUNCTION__, res));
 
-	set_ap_cfg(dev, ap_cfg);
 	kfree(extra);
 
 	return res;
@@ -1529,10 +1548,8 @@
 	dwrq->length = sizeof(struct iw_range);
 	memset(range, 0, sizeof(range));
 
-	
 	range->min_nwid = range->max_nwid = 0;
 
-	
 	list->count = htod32(MAXCHANNEL);
 	if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, sizeof(channels))))
 		return error;
@@ -1550,7 +1567,6 @@
 	}
 	range->num_frequency = range->num_channels = i;
 
-	
 	range->max_qual.qual = 5;
 	
 	range->max_qual.level = 0x100 - 200;	
@@ -1568,7 +1584,6 @@
 	range->avg_qual.noise = 0x100 - 75;	
 #endif 
 
-	
 	if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset))))
 		return error;
 	rateset.count = dtoh32(rateset.count);
@@ -1605,7 +1620,6 @@
 		}
 	}
 
-	
 	if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i))))
 		return error;
 	i = dtoh32(i);
@@ -1614,7 +1628,6 @@
 	else
 		range->throughput = 1500000;	
 
-	
 	range->min_rts = 0;
 	range->max_rts = 2347;
 	range->min_frag = 256;
@@ -1631,7 +1644,6 @@
 #endif
 	range->encoding_size[3] = AES_KEY_SIZE;
 
-	
 	range->min_pmp = 0;
 	range->max_pmp = 0;
 	range->min_pmt = 0;
@@ -1639,7 +1651,6 @@
 	range->pmp_flags = 0;
 	range->pm_capa = 0;
 
-	
 	range->num_txpower = 2;
 	range->txpower[0] = 1;
 	range->txpower[1] = 255;
@@ -1649,7 +1660,6 @@
 	range->we_version_compiled = WIRELESS_EXT;
 	range->we_version_source = 19;
 
-	
 	range->retry_capa = IW_RETRY_LIMIT;
 	range->retry_flags = IW_RETRY_LIMIT;
 	range->r_time_flags = 0;
@@ -1669,9 +1679,8 @@
 	range->enc_capa |= IW_ENC_CAPA_WPA2;
 #endif
 
-	
 	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
-	
+
 	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
 	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
 	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
@@ -2194,7 +2203,7 @@
 	status = WL_SCAN_RESULTS_PARTIAL;
 	while (down_interruptible(&iscan->sysioc_sem) == 0) {
 
-#ifdef SOFTAP
+#if defined(SOFTAP)
 		if (ap_cfg_running) {
 			WL_TRACE(("%s skipping SCAN ops in AP mode !!!\n", __FUNCTION__));
 			continue;
@@ -3256,7 +3265,9 @@
 	if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &g_ssid, sizeof(g_ssid))))
 		return error;
 
-	WL_TRACE(("%s: join SSID=%s\n", __FUNCTION__,  g_ssid.SSID));
+	if (g_ssid.SSID_len) {
+		WL_TRACE(("%s: join SSID=%s\n", __FUNCTION__,  g_ssid.SSID));
+	}
 	return 0;
 }
 
@@ -4524,6 +4535,7 @@
 
 #endif 
 
+
 int dev_iw_write_cfg1_bss_var(struct net_device *dev, int val)
 {
 	struct {
@@ -4540,11 +4552,28 @@
 
 	bss_set_res = dev_iw_iovar_setbuf(dev, "bss",
 		&bss_setbuf, sizeof(bss_setbuf), smbuf, sizeof(smbuf));
-	WL_TRACE(("\n:%s: bss_set_result:%d\n", __FUNCTION__, bss_set_res));
+	WL_TRACE(("%s: bss_set_result:%d set with %d\n", __FUNCTION__, bss_set_res, val));
 
 	return bss_set_res;
 }
 
+
+int dev_iw_read_cfg1_bss_var(struct net_device *dev, int *val)
+{
+	int bsscfg_idx = 1;
+	int bss_set_res;
+	char smbuf[WLC_IOCTL_SMLEN];
+	memset(smbuf, 0, sizeof(smbuf));
+
+	bss_set_res = dev_iw_iovar_getbuf(dev, "bss", \
+		 &bsscfg_idx, sizeof(bsscfg_idx), smbuf, sizeof(smbuf));
+	*val = *(int*)smbuf;
+	*val = dtoh32(*val);
+	WL_TRACE(("%s: status=%d bss_get_result=%d\n", __FUNCTION__, bss_set_res, *val));
+	return bss_set_res;
+}
+
+
 static int wl_bssiovar_mkbuf(
 			const char *iovar,
 			int bssidx,
@@ -4609,6 +4638,7 @@
 
 static int thr_wait_for_2nd_eth_dev(void *data)
 {
+	int ret = 0;
 
 	DAEMONIZE("wl0_eth_wthread");
 
@@ -4616,27 +4646,78 @@
 
 	if (down_timeout(&ap_eth_sema,  msecs_to_jiffies(5000)) != 0) {
 		WL_ERROR(("\n%s: sap_eth_sema timeout \n", __FUNCTION__));
-		return -1;
+		ret = -1;
+		goto fail;
 	}
 
 	if (!ap_net_dev) {
 		WL_ERROR((" ap_net_dev is null !!!"));
-		return -1;
+		ret = -1;
+		goto fail;
 	}
 
 	WL_TRACE(("\n>%s: Thread:'softap ethdev IF:%s is detected !!!'\n\n",
 		__FUNCTION__, ap_net_dev->name));
 
-	ap_mode = 1;
 	ap_cfg_running = TRUE;
 
 	bcm_mdelay(500);
 
-	wl_iw_send_priv_event(priv_dev, "ASCII_CMD=AP_BSS_START");
+	wl_iw_send_priv_event(priv_dev, "AP_SET_CFG_OK");
 
+fail:
 	WL_TRACE(("\n>%s, thread completed\n", __FUNCTION__));
 
-	return 0;
+	return ret;
+}
+
+static int get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap)
+{
+	int chosen = 0;
+	wl_uint32_list_t request;
+	int rescan = 0;
+	int retry = 0;
+	int updown = 0;
+	int ret = 0;
+	wlc_ssid_t null_ssid;
+	int res = 0;
+
+	WL_SOFTAP(("Enter %s\n", __FUNCTION__));
+	memset(&null_ssid, 0, sizeof(wlc_ssid_t));
+	res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown));
+	res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &null_ssid, sizeof(null_ssid));
+
+	auto_channel_retry:
+			request.count = htod32(0);
+			ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request));
+			if (ret < 0) {
+				WL_ERROR(("can't start auto channel scan\n"));
+				goto fail;
+			}
+
+	get_channel_retry:
+			bcm_mdelay(500);
+
+			ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen));
+			if (ret < 0 || dtoh32(chosen) == 0) {
+				if (retry++ < 3)
+					goto get_channel_retry;
+				else {
+					WL_ERROR(("can't get auto channel sel, err = %d, \
+						chosen = %d\n", ret, chosen));
+					goto fail;
+				}
+			}
+			if ((chosen == 1) && (!rescan++))
+				goto auto_channel_retry;
+			WL_SOFTAP(("Set auto channel = %d\n", chosen));
+			ap->channel = chosen;
+			if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) {
+				WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res));
+				goto fail;
+			}
+fail :
+	return res;
 }
 
 
@@ -4646,7 +4727,6 @@
 	int channel = 0;
 
 	wlc_ssid_t ap_ssid;
-	wlc_ssid_t null_ssid;
 	int max_assoc = 8;
 	int mpc = 0;
 
@@ -4657,9 +4737,13 @@
 	int bsscfg_index = 1;
 	char buf[WLC_IOCTL_SMLEN];
 
-	ap_mode = 0;
+	if (!dev) {
+		WL_ERROR(("%s: dev is null\n", __FUNCTION__));
+		return -1;
+	}
 
-	memset(&null_ssid, 0, sizeof(wlc_ssid_t));
+    net_os_wake_lock(dev);
+
 	WL_SOFTAP(("wl_iw: set ap profile:\n"));
 	WL_SOFTAP(("	ssid = '%s'\n", ap->ssid));
 	WL_SOFTAP(("	security = '%s'\n", ap->sec));
@@ -4668,89 +4752,95 @@
 	WL_SOFTAP(("	channel = %d\n", ap->channel));
 	WL_SOFTAP(("	max scb = %d\n", ap->max_scb));
 
-	if (!ap_cfg_running) {
+	if (ap_cfg_running == FALSE) {
 
 		sema_init(&ap_eth_sema, 0);
 
 		mpc = 0;
-		res |= dev_wlc_intvar_set(dev, "mpc", mpc);
+		if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) {
+			WL_ERROR(("%s fail to set mpc\n", __FUNCTION__));
+			goto fail;
+		}
 
 		updown = 0;
-		res |= dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown));
+		if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown)))) {
+			WL_ERROR(("%s fail to set updown\n", __FUNCTION__));
+			goto fail;
+		}
 
 #ifdef AP_ONLY
 		apsta_var = 0;
-		res | = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var));
-
+		if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) {
+			WL_ERROR(("%s fail to set apsta_var 0\n", __FUNCTION__));
+			goto fail;
+		}
 		apsta_var = 1;
-		res |= dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var));
-		res |= dev_wlc_ioctl(dev, WLC_GET_AP, &apsta_var, sizeof(apsta_var));
+		if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) {
+			WL_ERROR(("%s fail to set apsta_var 1\n", __FUNCTION__));
+			goto fail;
+		}
+		res = dev_wlc_ioctl(dev, WLC_GET_AP, &apsta_var, sizeof(apsta_var));
 #else
 		apsta_var = 1;
-		iolen = wl_bssiovar_mkbuf("apsta", bsscfg_index, &apsta_var,
-				sizeof(apsta_var)+4, buf, sizeof(buf), &mkvar_err);
+		iolen = wl_bssiovar_mkbuf("apsta",
+			bsscfg_index,  &apsta_var, sizeof(apsta_var)+4,
+			buf, sizeof(buf), &mkvar_err);
 		ASSERT(iolen);
-		res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen);
+		if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) {
+			WL_ERROR(("%s fail to set apsta \n", __FUNCTION__));
+			goto fail;
+		}
 		WL_TRACE(("\n>in %s: apsta set result: %d \n", __FUNCTION__, res));
 #endif
 
 		updown = 1;
-		res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown));
-		WL_TRACE(("\n:%s >>>> dev_wlc_ioctl(WLC_UP) updown:%d, \n", __FUNCTION__, updown));
+		if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown))) < 0) {
+			WL_ERROR(("%s fail to set apsta \n", __FUNCTION__));
+			goto fail;
+		}
 
 	} else {
+		
+		if (!ap_net_dev) {
+			WL_ERROR(("%s: ap_net_dev is null\n", __FUNCTION__));
+			goto fail;
+		}
 
-		res |= dev_iw_write_cfg1_bss_var(dev, 0);
+		res = wl_iw_softap_deassoc_stations(ap_net_dev);
+
+		
+		if ((res = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) {
+			WL_ERROR(("%s fail to set bss down\n", __FUNCTION__));
+			goto fail;
+		}
 	}
 
-	if (ap->channel == 0) {
-		int chosen = 0;
-		wl_uint32_list_t request;
-		int rescan = 0;
-		int retry = 0;
-		int ret = 0;
-
-		res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown));
-		res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &null_ssid, sizeof(null_ssid));
-
-auto_channel_retry:
-		request.count = htod32(0);
-		ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request));
-		if (ret < 0) {
-			WL_ERROR(("can't start auto channel scan\n"));
-			return -1;
-		}
-
-get_channel_retry:
-		bcm_mdelay(500);
-
-		ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen));
-		if (ret < 0 || dtoh32(chosen) == 0) {
-			if (retry++ < 3)
-				goto get_channel_retry;
-			else {
-				WL_ERROR(("can't get auto channel sel, err = %d, \
-					chosen = %d\n", ret, chosen));
-				return -1;
-			}
-		}
-		if ((chosen == 1) && (!rescan++))
-			goto auto_channel_retry;
-		WL_SOFTAP(("Set auto channel = %d\n", chosen));
-		ap->channel = chosen;
-		dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown));
+	
+	if ((ap->channel == 0) && (get_softap_auto_channel(dev, ap) < 0)) {
+		ap->channel = 1;
+		WL_ERROR(("%s auto channel failed, pick up channel=%d\n", \
+			__FUNCTION__, ap->channel));
 	}
 
 	channel = ap->channel;
-	res |= dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel));
+	if ((res = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel)))) {
+			WL_ERROR(("%s fail to set channel\n", __FUNCTION__));
+			goto fail;
+	}
 
-	if (!ap_cfg_running) {
+	if (ap_cfg_running == FALSE) {
 		updown = 0;
-		res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown));
+		if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)))) {
+			WL_ERROR(("%s fail to set up\n", __FUNCTION__));
+			goto fail;
+		}
 	}
 
 	max_assoc = ap->max_scb;
-	res |= dev_wlc_intvar_set(dev, "maxassoc", max_assoc);
+	if ((res = dev_wlc_intvar_set(dev, "maxassoc", max_assoc))) {
+			WL_ERROR(("%s fail to set maxassoc\n", __FUNCTION__));
+			goto fail;
+	}
 
 	ap_ssid.SSID_len = strlen(ap->ssid);
 	strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len);
@@ -4758,29 +4848,38 @@
 	iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&ap_ssid),
 		ap_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err);
 	ASSERT(iolen);
-	res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen);
-
-	if (res != 0) {
-		WL_ERROR(("ERROR:%d in:%s, Security & BSS reconfiguration is skipped\n",
-			res, __FUNCTION__));
-		return res;
+	if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) != 0) {
+		WL_ERROR(("ERROR:%d in:%s, Security & BSS reconfiguration is skipped\n", \
+		res, __FUNCTION__));
+		goto fail;
 	}
-
-	if (!ap_cfg_running) {
+	if (ap_cfg_running == FALSE) {
 		kernel_thread(thr_wait_for_2nd_eth_dev, 0, 0);
 	} else {
 		if (ap_net_dev == NULL) {
-			WL_ERROR(("%s: ERROR: ap_net_dev is NULL !!!\n",__FUNCTION__));
-			return -1;
+			WL_ERROR(("%s ERROR: ap_net_dev is NULL !!!\n", __FUNCTION__));
+			goto fail;
 		}
 
-		/* if  the AP interface wl0.1 already exists we call security & bss UP in here */
-		WL_ERROR(("%s: %s Configure security & restart AP bss\n", __FUNCTION__, ap_net_dev->name));
+		WL_ERROR(("%s: %s Configure security & restart AP bss \n", \
+			 __FUNCTION__, ap_net_dev->name));
 
-		res |= wl_iw_set_ap_security(ap_net_dev, &my_ap);
-		res |= dev_iw_write_cfg1_bss_var(dev, 1);
+		if ((res = wl_iw_set_ap_security(ap_net_dev, &my_ap)) < 0) {
+			WL_ERROR(("%s fail to set security : %d\n", __FUNCTION__, res));
+			goto fail;
+		}
+
+		if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) {
+			WL_ERROR(("%s fail to set bss up\n", __FUNCTION__));
+			goto fail;
+		}
 	}
-	return res;
+fail:
+	WL_SOFTAP(("%s exit with %d\n", __FUNCTION__, res));
+
+    net_os_wake_unlock(dev);
+
+    return res;
 }
 
 
@@ -5042,6 +5141,10 @@
 
 	if (res != 0)
 		WL_SOFTAP((" Error:%d in :%s\n", res, __FUNCTION__));
+	else if (assoc_maclist->count) {
+		
+		bcm_mdelay(200);
+	}
 	return res;
 }
 
@@ -5060,16 +5163,27 @@
 		return res;
 	}
 
-	res = wl_iw_softap_deassoc_stations(ap_net_dev);
+    net_os_wake_lock(dev);
 
-	bcm_mdelay(200);
-	res |= dev_iw_write_cfg1_bss_var(dev, 2);
+	if ((ap_cfg_running == TRUE)) {
+        wl_iw_softap_deassoc_stations(ap_net_dev);
 
-	wrqu->data.length = 0;
-	ap_mode = 0;
-	ap_cfg_running = FALSE;
+		if ((res = dev_iw_write_cfg1_bss_var(dev, 2)) < 0)
+			WL_ERROR(("%s failed to del BSS err = %d", __FUNCTION__, res));
 
-	return res;
+		bcm_mdelay(100);
+
+		wrqu->data.length = 0;
+		ap_cfg_running = FALSE;
+	}
+	else
+		WL_ERROR(("%s: was called when SoftAP is OFF : move on\n", __FUNCTION__));
+
+	WL_SOFTAP(("%s Done with %d\n", __FUNCTION__, res));
+
+    net_os_wake_unlock(dev);
+
+    return res;
 }
 
 
@@ -5090,7 +5204,6 @@
 				info->cmd, info->flags,
 				wrqu->data.pointer, wrqu->data.length, fwstr, strlen(fwstr)));
 
-
 	if ((wrqu->data.length > 4) && (wrqu->data.length < sizeof(extra))) {
 
 		char *str_ptr;
@@ -5174,13 +5287,30 @@
 		char *extra)
 {
 	int res = 0;
+
+	if (!dev) {
+		WL_ERROR(("%s: dev is null\n", __FUNCTION__));
+		return -1;
+	}
+
+    net_os_wake_lock(dev);
+
 	WL_TRACE(("%s: rcvd IWPRIV IOCTL:  for dev:%s\n", __FUNCTION__, dev->name));
 
-	if (wl_iw_set_ap_security(dev, &my_ap) != 0) {
-		WL_ERROR(("!!!!:ERROR setting SOFTAP security in :%s\n", __FUNCTION__));
-	};
+	if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) {
+		WL_ERROR((" %s ERROR setting SOFTAP security in :%d\n", __FUNCTION__, res));
+	}
+	else {
+		if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0)
+			WL_ERROR(("%s fail to set bss up err=%d\n", __FUNCTION__, res));
+		else
+			bcm_mdelay(100);
+	}
 
-	dev_iw_write_cfg1_bss_var(dev, 1);
+	WL_SOFTAP(("%s done with res %d \n", __FUNCTION__, res));
+
+    net_os_wake_unlock(dev);
+
 	return res;
 }
 
@@ -5296,13 +5426,12 @@
 
 		WL_SOFTAP((" AP_CFG \n"));
 
-		ap_mode = 0;
 
 		if (init_ap_profile_from_string(cmd_str+PROFILE_OFFSET, &my_ap) != 0) {
 			WL_ERROR(("ERROR: SoftAP CFG prams !\n"));
 			ret = -1;
 		} else {
-			set_ap_cfg(dev, &my_ap);
+			ret = set_ap_cfg(dev, &my_ap);
 		}
 
 	} else if (strnicmp(sub_cmd, "AP_BSS_START", strlen("AP_BSS_START")) == 0) {
@@ -5314,14 +5443,19 @@
 		if (ap_net_dev == NULL) {
 			printf("\n ERROR: SOFTAP net_dev* is NULL !!!\n");
 		} else {
-			iwpriv_en_ap_bss(ap_net_dev, info, dwrq, cmd_str);
+			if ((ret = iwpriv_en_ap_bss(ap_net_dev, info, dwrq, cmd_str)) < 0)
+				WL_ERROR(("%s line %d fail to set bss up\n", \
+					__FUNCTION__, __LINE__));
 		}
 
 	} else if (strnicmp(sub_cmd, "ASSOC_LST", strlen("ASSOC_LST")) == 0) {
 		/* no code yet */
 	} else if (strnicmp(sub_cmd, "AP_BSS_STOP", strlen("AP_BSS_STOP")) == 0) {
 		WL_SOFTAP((" \n temp DOWN SOFTAP\n"));
-		ret = dev_iw_write_cfg1_bss_var(dev, 0);
+		if ((ret = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) {
+				WL_ERROR(("%s line %d fail to set bss down\n", \
+					__FUNCTION__, __LINE__));
+		}
 	}
 
 	return ret;
@@ -5386,8 +5520,15 @@
 			ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra);
 		else if (strnicmp(extra, "STOP", strlen("STOP")) == 0)
 			ret = wl_iw_control_wl_off(dev, info);
+#ifdef CUSTOMER_HW2
+		else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0)
+			ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra);
+		else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0)
+			ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra);
+#else
 		else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0)
 			ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra);
+#endif
 #ifdef SOFTAP
 		else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) {
 			wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra);
@@ -5883,12 +6024,14 @@
 		return;
 	}
 
+    net_os_wake_lock(dev);
+
 	WL_TRACE(("%s: dev=%s event=%d \n", __FUNCTION__, dev->name, event_type));
 
 	switch (event_type) {
 #if defined(SOFTAP)
 	case WLC_E_PRUNE:
-		if (ap_mode) {
+		if (ap_cfg_running) {
 			char *macaddr = (char *)&e->addr;
 			WL_SOFTAP(("PRUNE received, %02X:%02X:%02X:%02X:%02X:%02X!\n",
 				macaddr[0], macaddr[1], macaddr[2], macaddr[3], \
@@ -5926,9 +6069,9 @@
 	case WLC_E_REASSOC_IND:
 #if defined(SOFTAP)
 		WL_SOFTAP(("STA connect received %d\n", event_type));
-		if (ap_mode) {
+		if (ap_cfg_running) {
 			wl_iw_send_priv_event(priv_dev, "STA_JOIN");
-			return;
+            goto wl_iw_event_end;
 		}
 #endif
 		memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN);
@@ -5939,9 +6082,9 @@
 	case WLC_E_DISASSOC_IND:
 #if defined(SOFTAP)
 		WL_SOFTAP(("STA disconnect received %d\n", event_type));
-		if (ap_mode) {
+		if (ap_cfg_running) {
 			wl_iw_send_priv_event(priv_dev, "STA_LEAVE");
-			return;
+            goto wl_iw_event_end;
 		}
 #endif
 		cmd = SIOCGIWAP;
@@ -5954,7 +6097,7 @@
 		cmd = SIOCGIWAP;
 		if (!(flags & WLC_EVENT_MSG_LINK)) {
 #ifdef SOFTAP
-			if (ap_mode && !strncmp(dev->name, "wl0.1", 5)) {
+		if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) {
 				WL_SOFTAP(("AP DOWN %d\n", event_type));
 				wl_iw_send_priv_event(priv_dev, "AP_DOWN");
 			} else {
@@ -5968,16 +6111,16 @@
 
 			bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
 			bzero(&extra, ETHER_ADDR_LEN);
+            net_os_wake_lock_timeout_enable(dev);
 		}
 		else {
-			
 			memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN);
 			g_ss_cache_ctrl.m_link_down = 0;
-			
+
 			memcpy(g_ss_cache_ctrl.m_active_bssid, &e->addr, ETHER_ADDR_LEN);
 
 #ifdef SOFTAP
-			if (ap_mode && !strncmp(dev->name, "wl0.1", 5)) {
+			if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) {
 				WL_SOFTAP(("AP UP %d\n", event_type));
 				wl_iw_send_priv_event(priv_dev, "AP_UP");
 			} else {
@@ -6053,7 +6196,7 @@
 				count--;
 			}
 		}
-		return;
+		goto wl_iw_event_end;
 	}
 #endif 
 #endif 
@@ -6102,8 +6245,9 @@
 		wireless_send_event(dev, cmd, &wrqu, extra);
 #endif
 	}
-#endif 
-
+#endif
+wl_iw_event_end:
+    net_os_wake_unlock(dev);
 #endif 
 }
 
@@ -6374,6 +6518,9 @@
 
 	iw = *(wl_iw_t **)netdev_priv(dev);
 	iw->pub = (dhd_pub_t *)dhdp;
+#ifdef SOFTAP
+	priv_dev = dev;
+#endif 
 	g_scan = NULL;
 
 	g_scan = (void *)kmalloc(G_SCAN_RESULTS, GFP_KERNEL);
@@ -6387,9 +6534,6 @@
 
 	wl_iw_bt_init(dev);
 
-#ifdef SOFTAP
-	priv_dev = dev;
-#endif
 
 	return 0;
 }
@@ -6424,7 +6568,7 @@
 	wl_iw_release_ss_cache_ctrl();
 	wl_iw_bt_release();
 #ifdef SOFTAP
-	if (ap_mode) {
+	if (ap_cfg_running) {
 		WL_TRACE(("\n%s AP is going down\n", __FUNCTION__));
 		wl_iw_send_priv_event(priv_dev, "AP_DOWN");
 	}
diff --git a/bcm4329/src/wl/sys/wl_iw.h b/bcm4329/src/wl/sys/wl_iw.h
index c22dc72..aea656b 100644
--- a/bcm4329/src/wl/sys/wl_iw.h
+++ b/bcm4329/src/wl/sys/wl_iw.h
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: wl_iw.h,v 1.5.34.1.6.15 2010/03/29 23:51:17 Exp $
+ * $Id: wl_iw.h,v 1.5.34.1.6.16 2010/04/19 21:32:10 Exp $
  */
 
 
@@ -90,15 +90,7 @@
 	dhd_pub_t * pub;
 } wl_iw_t;
 
-struct wl_ctrl {
-	struct timer_list *timer;
-	struct net_device *dev;
-	long sysioc_pid;
-	struct semaphore timer_sem;
-	struct completion sysioc_exited;
-};
-
-#define WLC_IW_SS_CACHE_MAXLEN			512
+#define WLC_IW_SS_CACHE_MAXLEN				512
 #define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN	32
 #define WLC_IW_BSS_INFO_MAXLEN 				\
 	(WLC_IW_SS_CACHE_MAXLEN - WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)