From 145537d0b103eaba569e1cc17ffd47668bc12a48 Mon Sep 17 00:00:00 2001
From: Greg Goldman <ggoldman@broadcom.com>
Date: Wed, 15 Sep 2010 15:05:19 -0700
Subject: [PATCH] net: wireless: bcm4329: Update to Version 4.218.248.6

Fix watchdog time rescheduling, fix first scan no-return

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
---
 drivers/net/wireless/bcm4329/bcmsdh_linux.c   | 12 +++-
 drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c   |  8 ++-
 drivers/net/wireless/bcm4329/dhd_common.c     | 50 +++++++++++++-
 .../net/wireless/bcm4329/dhd_custom_gpio.c    |  4 +-
 drivers/net/wireless/bcm4329/dhd_linux.c      | 31 ++++++---
 drivers/net/wireless/bcm4329/dhd_sdio.c       |  6 +-
 .../net/wireless/bcm4329/include/epivers.h    | 10 +--
 drivers/net/wireless/bcm4329/wl_iw.c          | 67 +++++++++++++------
 drivers/net/wireless/bcm4329/wl_iw.h          | 10 +--
 9 files changed, 147 insertions(+), 51 deletions(-)

diff --git a/drivers/net/wireless/bcm4329/bcmsdh_linux.c b/drivers/net/wireless/bcm4329/bcmsdh_linux.c
index 644d6be577d6..559f4819b1b6 100644
--- a/drivers/net/wireless/bcm4329/bcmsdh_linux.c
+++ b/drivers/net/wireless/bcm4329/bcmsdh_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_linux.c,v 1.42.10.10.2.14 2010/08/17 16:34:23 Exp $
+ * $Id: bcmsdh_linux.c,v 1.42.10.10.2.14.4.2 2010/09/15 00:30:11 Exp $
  */
 
 /**
@@ -180,7 +180,7 @@ int bcmsdh_probe(struct device *dev)
 #endif /* BCMLXSDMMC */
 	int irq = 0;
 	uint32 vendevid;
-	unsigned long irq_flags = IRQF_TRIGGER_FALLING;
+	unsigned long irq_flags = 0;
 
 #if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
 	pdev = to_platform_device(dev);
@@ -191,6 +191,12 @@ int bcmsdh_probe(struct device *dev)
 #endif /* BCMLXSDMMC */
 
 #if defined(OOB_INTR_ONLY)
+#ifdef HW_OOB
+	irq_flags = \
+		IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE;
+#else
+	 irq_flags = IRQF_TRIGGER_FALLING;
+#endif /* HW_OOB */
 	irq = dhd_customer_oob_irq_map(&irq_flags);
 	if  (irq < 0) {
 		SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__));
@@ -621,6 +627,8 @@ int bcmsdh_register_oob_intr(void * dhdp)
 	dev_set_drvdata(sdhcinfo->dev, dhdp);
 
 	if (!sdhcinfo->oob_irq_registered) {
+		SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, \
+				(int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags));
 		/* Refer to customer Host IRQ docs about proper irqflags definition */
 		error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags,
 			"bcmsdh_sdmmc", NULL);
diff --git a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c b/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c
index 5a3ca3d11893..bda919390587 100644
--- a/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/bcm4329/bcmsdh_sdmmc.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.c,v 1.1.2.5.6.29 2010/03/19 17:16:08 Exp $
+ * $Id: bcmsdh_sdmmc.c,v 1.1.2.5.6.30.4.1 2010/09/02 23:12:21 Exp $
  */
 #include <typedefs.h>
 
@@ -55,7 +55,7 @@ extern void sdio_function_cleanup(void);
 #if !defined(OOB_INTR_ONLY)
 static void IRQHandler(struct sdio_func *func);
 static void IRQHandlerF2(struct sdio_func *func);
-#endif
+#endif /* !defined(OOB_INTR_ONLY) */
 static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr);
 extern int sdio_reset_comm(struct mmc_card *card);
 
@@ -1066,11 +1066,13 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
 	return (Status);
 }
 
+/* this function performs "abort" for both of host & device */
 extern int
 sdioh_abort(sdioh_info_t *sd, uint func)
 {
+#if defined(MMC_SDIO_ABORT)
 	char t_func = (char) func;
-
+#endif /* defined(MMC_SDIO_ABORT) */
 	sd_trace(("%s: Enter\n", __FUNCTION__));
 
 #if defined(MMC_SDIO_ABORT)
diff --git a/drivers/net/wireless/bcm4329/dhd_common.c b/drivers/net/wireless/bcm4329/dhd_common.c
index e3e8dcc1a510..bea33b6d29af 100644
--- a/drivers/net/wireless/bcm4329/dhd_common.c
+++ b/drivers/net/wireless/bcm4329/dhd_common.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_common.c,v 1.5.6.8.2.6.6.69 2010/08/20 00:39:21 Exp $
+ * $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.3 2010/09/10 21:30:16 Exp $
  */
 #include <typedefs.h>
 #include <osl.h>
@@ -1312,6 +1312,52 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 	bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf));
 	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
 
+	if (dhd_roam == 0)
+	{
+		/* set internal roaming roaming parameters */
+		int roam_scan_period = 30; /* in sec */
+		int roam_fullscan_period = 120; /* in sec */
+		int roam_trigger = -85;
+		int roam_delta = 15;
+		int band;
+		int band_temp_set = WLC_BAND_2G;
+
+		if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_SCAN_PERIOD, \
+			(char *)&roam_scan_period, sizeof(roam_scan_period)) < 0)
+			DHD_ERROR(("%s: roam scan setup failed\n", __FUNCTION__));
+
+		bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, \
+					 4, iovbuf, sizeof(iovbuf));
+		if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, \
+			iovbuf, sizeof(iovbuf)) < 0)
+			DHD_ERROR(("%s: roam fullscan setup failed\n", __FUNCTION__));
+
+		if (dhdcdc_query_ioctl(dhd, 0, WLC_GET_BAND, \
+				(char *)&band, sizeof(band)) < 0)
+			DHD_ERROR(("%s: roam delta setting failed\n", __FUNCTION__));
+		else {
+			if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_ALL))
+			{
+				/* temp set band to insert new roams values */
+				if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_BAND, \
+					(char *)&band_temp_set, sizeof(band_temp_set)) < 0)
+					DHD_ERROR(("%s: local band seting failed\n", __FUNCTION__));
+			}
+			if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_DELTA, \
+				(char *)&roam_delta, sizeof(roam_delta)) < 0)
+				DHD_ERROR(("%s: roam delta setting failed\n", __FUNCTION__));
+
+			if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_TRIGGER, \
+				(char *)&roam_trigger, sizeof(roam_trigger)) < 0)
+				DHD_ERROR(("%s: roam trigger setting failed\n", __FUNCTION__));
+
+			/* Restore original band settinngs */
+			if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_BAND, \
+				(char *)&band, sizeof(band)) < 0)
+				DHD_ERROR(("%s: Original band restore failed\n", __FUNCTION__));
+		}
+	}
+
 	/* Force STA UP */
 	if (dhd_radio_up)
 		dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up));
@@ -1790,7 +1836,7 @@ int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
 
 /* Function to execute combined scan */
 int
-dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, uchar scan_fr)
+dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr)
 {
 	int err = -1;
 	char iovbuf[128];
diff --git a/drivers/net/wireless/bcm4329/dhd_custom_gpio.c b/drivers/net/wireless/bcm4329/dhd_custom_gpio.c
index dc532330d8a4..8c6ec470b8bd 100644
--- a/drivers/net/wireless/bcm4329/dhd_custom_gpio.c
+++ b/drivers/net/wireless/bcm4329/dhd_custom_gpio.c
@@ -20,7 +20,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_custom_gpio.c,v 1.1.4.7 2010/06/03 21:27:48 Exp $
+* $Id: dhd_custom_gpio.c,v 1.1.4.8.4.1 2010/09/02 23:13:16 Exp $
 */
 
 
@@ -78,7 +78,7 @@ int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
 		dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
 	}
 #endif
-	*irq_flags_ptr = IRQF_TRIGGER_FALLING;
+
 	if (dhd_oob_gpio_num < 0) {
 		WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n",
 			__FUNCTION__));
diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c
index da8dac3237db..2eff4693d176 100644
--- a/drivers/net/wireless/bcm4329/dhd_linux.c
+++ b/drivers/net/wireless/bcm4329/dhd_linux.c
@@ -556,7 +556,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 				4, iovbuf, sizeof(iovbuf));
 			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
 #ifdef CUSTOMER_HW2
-			/* Disable build-in roaming to allowed ext supplicant to take of romaing */
+			/* Disable build-in roaming to allowed ext supplicant to take of roaming */
 			bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
 			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
 #endif /* CUSTOMER_HW2 */
@@ -1387,11 +1387,6 @@ dhd_watchdog_thread(void *data)
 			}
 			/* Count the tick for reference */
 			dhd->pub.tickcnt++;
-
-			/* Reschedule the watchdog */
-			if (dhd->wd_timer_valid) {
-				mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
-			}
 			dhd_os_wake_unlock(&dhd->pub);
 		}
 		else
@@ -1406,8 +1401,15 @@ dhd_watchdog(ulong data)
 {
 	dhd_info_t *dhd = (dhd_info_t *)data;
 
+	dhd_os_wake_lock(&dhd->pub);
 	if (dhd->watchdog_pid >= 0) {
 		up(&dhd->watchdog_sem);
+
+		/* Reschedule the watchdog */
+		if (dhd->wd_timer_valid) {
+				mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+		}
+		dhd_os_wake_unlock(&dhd->pub);
 		return;
 	}
 
@@ -1420,6 +1422,7 @@ dhd_watchdog(ulong data)
 	/* Reschedule the watchdog */
 	if (dhd->wd_timer_valid)
 		mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+	dhd_os_wake_unlock(&dhd->pub);
 }
 
 static int
@@ -1873,7 +1876,11 @@ dhd_open(struct net_device *net)
 	ifidx = dhd_net2idx(dhd, net);
 	DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
 
-	/* ASSERT(ifidx == 0); */
+	if ((dhd->iflist[ifidx]) && (dhd->iflist[ifidx]->state == WLC_E_IF_DEL)) {
+		DHD_ERROR(("%s: Error: called when IF already deleted\n", __FUNCTION__));
+		return -1;
+	}
+
 
 	if (ifidx == 0) { /* do it only for primary eth0 */
 
@@ -2841,6 +2848,14 @@ dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
 
 #if defined(CONFIG_WIRELESS_EXT)
 	ASSERT(dhd->iflist[*ifidx] != NULL);
+
+	if (ntoh32(event->event_type) == WLC_E_IF) {
+		DHD_INFO(("<0> interface:%d OP:%d don't pass to wext,"
+			"net_device might not be created yet\n",
+				*ifidx, ntoh32(event->event_type)));
+		return bcmerror;
+	}
+
 	ASSERT(dhd->iflist[*ifidx]->net != NULL);
 
 	if (dhd->iflist[*ifidx]->net)
@@ -2990,7 +3005,7 @@ dhd_dev_pno_enable(struct net_device *dev,  int pfn_enabled)
 
 /* Linux wrapper to call common dhd_pno_set */
 int
-dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, uchar  scan_fr)
+dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, ushort  scan_fr)
 {
 	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
 
diff --git a/drivers/net/wireless/bcm4329/dhd_sdio.c b/drivers/net/wireless/bcm4329/dhd_sdio.c
index 7b54f60e6f72..874ce16ce907 100644
--- a/drivers/net/wireless/bcm4329/dhd_sdio.c
+++ b/drivers/net/wireless/bcm4329/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.129 2010/08/19 20:36:22 Exp $
+ * $Id: dhd_sdio.c,v 1.157.2.27.2.33.2.129.4.1 2010/09/02 23:13:16 Exp $
  */
 
 #include <typedefs.h>
@@ -4218,11 +4218,9 @@ dhdsdio_dpc(dhd_bus_t *bus)
 	bus->intstatus = intstatus;
 
 clkwait:
-
 #if defined(OOB_INTR_ONLY)
 	bcmsdh_oob_intr_set(1);
-#endif
-
+#endif /* (OOB_INTR_ONLY) */
 	/* Re-enable interrupts to detect new device events (mailbox, rx frame)
 	 * or clock availability.  (Allows tx loop to check ipend if desired.)
 	 * (Unless register access seems hosed, as we may not be able to ACK...)
diff --git a/drivers/net/wireless/bcm4329/include/epivers.h b/drivers/net/wireless/bcm4329/include/epivers.h
index 51b0da353058..92dc32635a25 100644
--- a/drivers/net/wireless/bcm4329/include/epivers.h
+++ b/drivers/net/wireless/bcm4329/include/epivers.h
@@ -33,16 +33,16 @@
 
 #define	EPI_RC_NUMBER		248
 
-#define	EPI_INCREMENTAL_NUMBER	2
+#define	EPI_INCREMENTAL_NUMBER	6
 
 #define	EPI_BUILD_NUMBER	0
 
-#define	EPI_VERSION		4, 218, 248, 2
+#define	EPI_VERSION		4, 218, 248, 6
 
-#define	EPI_VERSION_NUM		0x04daf802
+#define	EPI_VERSION_NUM		0x04daf806
 
 
-#define	EPI_VERSION_STR		"4.218.248.2"
-#define	EPI_ROUTER_VERSION_STR	"4.219.248.2"
+#define	EPI_VERSION_STR		"4.218.248.6"
+#define	EPI_ROUTER_VERSION_STR	"4.219.248.6"
 
 #endif 
diff --git a/drivers/net/wireless/bcm4329/wl_iw.c b/drivers/net/wireless/bcm4329/wl_iw.c
index 4179b882ac59..2cd629cbd1c3 100644
--- a/drivers/net/wireless/bcm4329/wl_iw.c
+++ b/drivers/net/wireless/bcm4329/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.142 2010/08/20 19:12:47 Exp $
+ * $Id: wl_iw.c,v 1.51.4.9.2.6.4.142.4.13 2010/09/15 03:34:56 Exp $
  */
 
 
@@ -161,7 +161,9 @@ static wlc_ssid_t g_specific_ssid;
 static wlc_ssid_t g_ssid;
 
 static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl;	
-static volatile uint g_first_broadcast_scan;	
+static volatile uint g_first_broadcast_scan;
+static volatile uint g_first_counter_scans;
+#define MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN 3
 
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
@@ -258,7 +260,7 @@ wl_iw_set_scan(
 	char *extra
 );
 
-#if !defined(CSCAN)
+#ifndef CSCAN
 static int
 wl_iw_get_scan(
 	struct net_device *dev,
@@ -1171,7 +1173,7 @@ wl_iw_set_pno_set(
 #ifdef PNO_SET_DEBUG
 	int i;
 	char pno_in_example[] = {'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', \
-							'S', 0x01, 0x00, 0x00,
+							'S', 0x01, 0x01, 0x00,
 							'S',
 							0x04,
 							'B', 'R', 'C', 'M',
@@ -1179,7 +1181,8 @@ wl_iw_set_pno_set(
 							0x04,
 							'G', 'O', 'O', 'G',
 							'T',
-							0x0A,
+							0x00,
+							0x0A
 							};
 #endif
 
@@ -1245,7 +1248,7 @@ wl_iw_set_pno_set(
 					if ((res = wl_iw_parse_data_tlv(&str_ptr, \
 						&pno_time, \
 						sizeof(pno_time), \
-						type, sizeof(char), &tlv_size_left)) == -1) {
+						type, sizeof(short), &tlv_size_left)) == -1) {
 							WL_ERROR(("%s return %d\n", \
 							__FUNCTION__, res));
 							goto exit_proc;
@@ -1418,6 +1421,7 @@ wl_iw_control_wl_off(
 		g_scan_specified_ssid = 0;
 
 		g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE;
+		g_first_counter_scans = 0;
 #endif
 
 #if defined(BCMLXSDMMC)
@@ -2566,8 +2570,11 @@ wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action)
 	WL_SCAN(("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type));
 
 	
-	(void) dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, \
-		iscan->iscan_ex_param_size, iscan->ioctlbuf, sizeof(iscan->ioctlbuf));
+	if ((err = dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, \
+		iscan->iscan_ex_param_size, iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) {
+			WL_ERROR(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err));
+			err = -1;
+	}
 
 	return err;
 }
@@ -3219,14 +3226,6 @@ wl_iw_iscan_set_scan(
 		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
 			int as = 0;
 			struct iw_scan_req *req = (struct iw_scan_req *)extra;
-#if !defined(CSCAN)
-			if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) {
-				WL_TRACE(("%s First ISCAN in progress : ignoring SC = %s\n", \
-					 __FUNCTION__, req->essid));
-				ret = -EBUSY;
-				goto set_scan_end;
-			}
-#endif
 			ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len);
 			memcpy(ssid.SSID, req->essid, ssid.SSID_len);
 			ssid.SSID_len = htod32(ssid.SSID_len);
@@ -3246,6 +3245,23 @@ wl_iw_iscan_set_scan(
 	}
 #endif 
 
+#if !defined(CSCAN)
+	if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) {
+		if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) {
+
+			WL_ERROR(("%s Clean up First scan flag which is %d\n", \
+				 __FUNCTION__, g_first_broadcast_scan));
+			g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED;
+		}
+		else {
+			WL_ERROR(("%s Ignoring Broadcast Scan:First Scan is not done yet %d\n", \
+					__FUNCTION__, g_first_counter_scans));
+			ret = -EBUSY;
+			goto set_scan_end;
+		}
+	}
+#endif
+
 	wl_iw_iscan_set_scan_broadcast_prep(dev, 0);
 
 set_scan_end:
@@ -3402,7 +3418,7 @@ wl_iw_handle_scanresults_ies(char **event_p, char *end,
 	return 0;
 }
 
-#if !defined(CSCAN)
+#ifndef CSCAN
 static uint
 wl_iw_get_scan_prep(
 	wl_scan_results_t *list,
@@ -5701,9 +5717,18 @@ wl_iw_set_cscan(
 		}
 
 		if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) {
-			WL_ERROR(("%s First ISCAN in progress : ignoring\n",  __FUNCTION__));
-			res = -EBUSY;
-			goto exit_proc;
+			if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) {
+
+				WL_ERROR(("%s Clean up First scan flag which is %d\n", \
+						 __FUNCTION__, g_first_broadcast_scan));
+				g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED;
+			}
+			else {
+				WL_ERROR(("%s Ignoring CSCAN : First Scan is not done yet %d\n", \
+						__FUNCTION__, g_first_counter_scans));
+				res = -EBUSY;
+				goto exit_proc;
+			}
 		}
 
 		res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan);
@@ -5872,6 +5897,7 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
 	if (ap_cfg_running == FALSE) {
 
 #ifndef AP_ONLY
+
 		sema_init(&ap_eth_sema, 0);
 
 		mpc = 0;
@@ -7769,6 +7795,7 @@ int wl_iw_attach(struct net_device *dev, void * dhdp)
 	iscan->dev = dev;
 	iscan->iscan_state = ISCAN_STATE_IDLE;
 	g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE;
+	g_first_counter_scans = 0;
 	g_iscan->scan_flag = 0;
 
 	iscan->timer_ms    = 8000;
diff --git a/drivers/net/wireless/bcm4329/wl_iw.h b/drivers/net/wireless/bcm4329/wl_iw.h
index 6381472f1bf9..43088cf886bd 100644
--- a/drivers/net/wireless/bcm4329/wl_iw.h
+++ b/drivers/net/wireless/bcm4329/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.35 2010/08/20 02:42:33 Exp $
+ * $Id: wl_iw.h,v 1.5.34.1.6.36.4.1 2010/09/10 19:24:30 Exp $
  */
 
 
@@ -49,7 +49,7 @@
 #define DTIM_SKIP_SET_CMD			"DTIMSKIPSET"
 #define SETSUSPEND_CMD				"SETSUSPENDOPT"
 #define PNOSSIDCLR_SET_CMD			"PNOSSIDCLR"
-#define PNOSETUP_SET_CMD			"PNOSETUP"
+#define PNOSETUP_SET_CMD			"PNOSETUP "
 #define PNOENABLE_SET_CMD			"PNOFORCE"
 #define PNODEBUG_SET_CMD			"PNODEBUG"
 
@@ -216,17 +216,17 @@ extern int net_os_send_hang_message(struct net_device *dev);
 
 extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
 extern int dhd_pno_clean(dhd_pub_t *dhd);
-extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, uchar  scan_fr);
+extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort  scan_fr);
 extern int dhd_pno_get_status(dhd_pub_t *dhd);
 extern int dhd_dev_pno_reset(struct net_device *dev);
 extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, \
-				 int nssid, uchar  scan_fr);
+				 int nssid, ushort  scan_fr);
 extern int dhd_dev_pno_enable(struct net_device *dev,  int pfn_enabled);
 extern int dhd_dev_get_pno_status(struct net_device *dev);
 
 #define PNO_TLV_PREFIX			'S'
 #define PNO_TLV_VERSION			1
-#define PNO_TLV_SUBVERSION 		0
+#define PNO_TLV_SUBVERSION 		1
 #define PNO_TLV_RESERVED		0
 #define PNO_TLV_TYPE_SSID_IE		'S'
 #define PNO_TLV_TYPE_TIME		'T'
-- 
2.34.1