net: wireless: bcmdhd: Update to Version 6.10.83.0 (1.23)

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index 96c3873..adb796c 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -19,7 +19,7 @@
 	-Idrivers/net/wireless/bcmdhd -Idrivers/net/wireless/bcmdhd/include
 
 DHDOFILES = aiutils.o bcmsdh_sdmmc_linux.o dhd_linux.o siutils.o bcmutils.o   \
-	dhd_linux_sched.o bcmwifi.o dhd_sdio.o bcmevent.o hndpmu.o  \
+	dhd_linux_sched.o dhd_sdio.o bcmwifi_channels.o bcmevent.o hndpmu.o   \
 	bcmsdh.o dhd_cdc.o bcmsdh_linux.o dhd_common.o linux_osl.o            \
 	bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o wl_android.o
 
diff --git a/drivers/net/wireless/bcmdhd/aiutils.c b/drivers/net/wireless/bcmdhd/aiutils.c
index 4361a44..f1db5a2 100644
--- a/drivers/net/wireless/bcmdhd/aiutils.c
+++ b/drivers/net/wireless/bcmdhd/aiutils.c
@@ -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: aiutils.c 309193 2012-01-19 00:03:57Z $
+ * $Id: aiutils.c 321247 2012-03-14 21:14:33Z $
  */
 #include <bcm_cfg.h>
 #include <typedefs.h>
@@ -673,6 +673,7 @@
 {
 	si_info_t *sii;
 	volatile uint32 dummy;
+	uint32 status;
 	aidmp_t *ai;
 
 	sii = SI_INFO(sih);
@@ -684,6 +685,18 @@
 	if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET)
 		return;
 
+	
+	SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
+
+	
+	if (status != 0) {
+		
+		
+		SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 10000);
+		
+		
+	}
+
 	W_REG(sii->osh, &ai->ioctrl, bits);
 	dummy = R_REG(sii->osh, &ai->ioctrl);
 	BCM_REFERENCE(dummy);
diff --git a/drivers/net/wireless/bcmdhd/bcmevent.c b/drivers/net/wireless/bcmdhd/bcmevent.c
index 3d805d0..04d04a9 100644
--- a/drivers/net/wireless/bcmdhd/bcmevent.c
+++ b/drivers/net/wireless/bcmdhd/bcmevent.c
@@ -20,7 +20,7 @@
  *      Notwithstanding the above, under no circumstances may you combine this
  * 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: bcmevent.c 300516 2011-12-04 17:39:44Z $
+ * $Id: bcmevent.c 320583 2012-03-12 15:09:36Z $
  */
 
 #include <typedefs.h>
@@ -29,7 +29,7 @@
 #include <proto/bcmeth.h>
 #include <proto/bcmevent.h>
 
-#if WLC_E_LAST != 89
+#if WLC_E_LAST != 93
 #error "You need to add an entry to bcmevent_names[] for the new event"
 #endif
 
@@ -126,7 +126,11 @@
 	{ WLC_E_GTK_PLUMBED, "GTK_PLUMBED" },
 #endif
 	{ WLC_E_ASSOC_REQ_IE, "ASSOC_REQ_IE" },
-	{ WLC_E_ASSOC_RESP_IE, "ASSOC_RESP_IE" }
+	{ WLC_E_ASSOC_RESP_IE, "ASSOC_RESP_IE" },
+	{ WLC_E_ACTION_FRAME_RX_NDIS, "WLC_E_ACTION_FRAME_RX_NDIS" },
+#ifdef WLTDLS
+	{ WLC_E_TDLS_PEER_EVENT, "TDLS_PEER_EVENT" },
+#endif /* WLTDLS */
 };
 
 const int bcmevent_names_size = ARRAYSIZE(bcmevent_names);
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
index 9c9856a..79760eb 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
+++ b/drivers/net/wireless/bcmdhd/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 309796 2012-01-20 18:21:51Z $
+ * $Id: bcmsdh_linux.c 312788 2012-02-03 23:06:32Z $
  */
 
 /**
@@ -515,24 +515,17 @@
 extern int sdio_func_reg_notify(void* semaphore);
 extern void sdio_func_unreg_notify(void);
 
+#if defined(BCMLXSDMMC)
 int bcmsdh_reg_sdio_notify(void* semaphore)
 {
-	int ret = -1;
-
-#ifdef BCMLXSDMMC
-	ret = sdio_func_reg_notify(semaphore);
-#endif
-
-	return ret;
+	return sdio_func_reg_notify(semaphore);
 }
 
 void bcmsdh_unreg_sdio_notify(void)
 {
-#ifdef BCMLXSDMMC
 	sdio_func_unreg_notify();
-#endif
-
 }
+#endif /* defined(BCMLXSDMMC) */
 
 int
 bcmsdh_register(bcmsdh_driver_t *driver)
@@ -642,12 +635,6 @@
 	return 0;
 }
 
-void *bcmsdh_get_drvdata(void)
-{
-	if (!sdhcinfo)
-		return NULL;
-	return dev_get_drvdata(sdhcinfo->dev);
-}
 void bcmsdh_set_irq(int flag)
 {
 	if (sdhcinfo->oob_irq_registered && sdhcinfo->oob_irq_enable_flag != flag) {
@@ -675,6 +662,15 @@
 }
 #endif /* defined(OOB_INTR_ONLY) */
 
+#if defined(BCMLXSDMMC)
+void *bcmsdh_get_drvdata(void)
+{
+	if (!sdhcinfo)
+		return NULL;
+	return dev_get_drvdata(sdhcinfo->dev);
+}
+#endif
+
 /* Module parameters specific to each host-controller driver */
 
 extern uint sd_msglevel;	/* Debug message level */
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
index 23a1f96..afe4019 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/bcmdhd/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 309548 2012-01-20 01:13:08Z $
+ * $Id: bcmsdh_sdmmc.c 321372 2012-03-15 01:10:32Z $
  */
 #include <typedefs.h>
 
@@ -35,6 +35,7 @@
 #include <sdiovar.h>	/* ioctl/iovars */
 
 #include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
 
@@ -148,6 +149,7 @@
 	sd->sd_blockmode = TRUE;
 	sd->use_client_ints = TRUE;
 	sd->client_block_size[0] = 64;
+	sd->use_rxchain = FALSE;
 
 	gInstance->sd = sd;
 
@@ -512,7 +514,7 @@
 	}
 
 	case IOV_GVAL(IOV_RXCHAIN):
-		int_val = FALSE;
+		int_val = (int32)si->use_rxchain;
 		bcopy(&int_val, arg, val_size);
 		break;
 
@@ -679,15 +681,10 @@
 	uint8 data;
 
 	if (enable)
-		data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;	/* enable hw oob interrupt */
+		data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE | SDIO_SEPINT_ACT_HI;
 	else
 		data = SDIO_SEPINT_ACT_HI;	/* disable hw oob interrupt */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
-	/* Needed for Android Linux Kernel 2.6.35 */
-	data |= SDIO_SEPINT_ACT_HI; 		/* Active HIGH */
-#endif
-
 	status = sdioh_request_byte(sd, SDIOH_WRITE, 0, SDIOD_CCCR_BRCM_SEPINT, &data);
 	return status;
 }
@@ -902,8 +899,12 @@
 	bool fifo = (fix_inc == SDIOH_DATA_FIX);
 	uint32	SGCount = 0;
 	int err_ret = 0;
-
-	void *pnext;
+	void *pnext, *pprev;
+	uint ttl_len, dma_len, lft_len, xfred_len, pkt_len;
+	uint blk_num;
+	struct mmc_request mmc_req;
+	struct mmc_command mmc_cmd;
+	struct mmc_data mmc_dat;
 
 	sd_trace(("%s: Enter\n", __FUNCTION__));
 
@@ -911,66 +912,148 @@
 	DHD_PM_RESUME_WAIT(sdioh_request_packet_wait);
 	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
 
-	/* Claim host controller */
-	sdio_claim_host(gInstance->func[func]);
-	for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) {
-		uint pkt_len = PKTLEN(sd->osh, pnext);
-		pkt_len += 3;
-		pkt_len &= 0xFFFFFFFC;
+	ttl_len = xfred_len = 0;
+	/* at least 4 bytes alignment of skb buff is guaranteed */
+	for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext))
+		ttl_len += PKTLEN(sd->osh, pnext);
 
-#ifdef CONFIG_MMC_MSM7X00A
-		if ((pkt_len % 64) == 32) {
-			sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__));
-			pkt_len += 32;
-		}
-#endif /* CONFIG_MMC_MSM7X00A */
-		/* Make sure the packet is aligned properly. If it isn't, then this
-		 * is the fault of sdioh_request_buffer() which is supposed to give
-		 * us something we can work with.
-		 */
-		ASSERT(((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) == 0);
+	if (!sd->use_rxchain || ttl_len <= sd->client_block_size[func]) {
+		blk_num = 0;
+		dma_len = 0;
+	} else {
+		blk_num = ttl_len / sd->client_block_size[func];
+		dma_len = blk_num * sd->client_block_size[func];
+	}
+	lft_len = ttl_len - dma_len;
 
-		if ((write) && (!fifo)) {
-			err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
-				((uint8*)PKTDATA(sd->osh, pnext)),
+	sd_trace(("%s: %s %dB to func%d:%08x, %d blks with DMA, %dB leftover\n",
+		__FUNCTION__, write ? "W" : "R",
+		ttl_len, func, addr, blk_num, lft_len));
+
+	if (0 != dma_len) {
+		memset(&mmc_req, 0, sizeof(struct mmc_request));
+		memset(&mmc_cmd, 0, sizeof(struct mmc_command));
+		memset(&mmc_dat, 0, sizeof(struct mmc_data));
+
+		/* Set up DMA descriptors */
+		pprev = pkt;
+		for (pnext = pkt;
+		     pnext && dma_len;
+		     pnext = PKTNEXT(sd->osh, pnext)) {
+			pkt_len = PKTLEN(sd->osh, pnext);
+
+			if (dma_len > pkt_len)
+				dma_len -= pkt_len;
+			else {
+				pkt_len = xfred_len = dma_len;
+				dma_len = 0;
+				pkt = pnext;
+			}
+
+			sg_set_buf(&sd->sg_list[SGCount++],
+				(uint8*)PKTDATA(sd->osh, pnext),
 				pkt_len);
-		} else if (write) {
-			err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
-				((uint8*)PKTDATA(sd->osh, pnext)),
-				pkt_len);
-		} else if (fifo) {
-			err_ret = sdio_readsb(gInstance->func[func],
-				((uint8*)PKTDATA(sd->osh, pnext)),
-				addr,
-				pkt_len);
-		} else {
-			err_ret = sdio_memcpy_fromio(gInstance->func[func],
-				((uint8*)PKTDATA(sd->osh, pnext)),
-				addr,
-				pkt_len);
+
+			if (SGCount >= SDIOH_SDMMC_MAX_SG_ENTRIES) {
+				sd_err(("%s: sg list entries exceed limit\n",
+					__FUNCTION__));
+				return (SDIOH_API_RC_FAIL);
+			}
 		}
 
-		if (err_ret) {
-			sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
-				__FUNCTION__,
-				(write) ? "TX" : "RX",
-				pnext, SGCount, addr, pkt_len, err_ret));
-		} else {
-			sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n",
-				__FUNCTION__,
-				(write) ? "TX" : "RX",
-				pnext, SGCount, addr, pkt_len));
-		}
+		mmc_dat.sg = sd->sg_list;
+		mmc_dat.sg_len = SGCount;
+		mmc_dat.blksz = sd->client_block_size[func];
+		mmc_dat.blocks = blk_num;
+		mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
 
-		if (!fifo) {
-			addr += pkt_len;
-		}
-		SGCount ++;
+		mmc_cmd.opcode = 53;		/* SD_IO_RW_EXTENDED */
+		mmc_cmd.arg = write ? 1<<31 : 0;
+		mmc_cmd.arg |= (func & 0x7) << 28;
+		mmc_cmd.arg |= 1<<27;
+		mmc_cmd.arg |= fifo ? 0 : 1<<26;
+		mmc_cmd.arg |= (addr & 0x1FFFF) << 9;
+		mmc_cmd.arg |= blk_num & 0x1FF;
+		mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
 
+		mmc_req.cmd = &mmc_cmd;
+		mmc_req.data = &mmc_dat;
+
+		sdio_claim_host(gInstance->func[func]);
+		mmc_set_data_timeout(&mmc_dat, gInstance->func[func]->card);
+		mmc_wait_for_req(gInstance->func[func]->card->host, &mmc_req);
+		sdio_release_host(gInstance->func[func]);
+
+		err_ret = mmc_cmd.error? mmc_cmd.error : mmc_dat.error;
+		if (0 != err_ret) {
+			sd_err(("%s:CMD53 %s failed with code %d\n",
+			       __FUNCTION__,
+			       write ? "write" : "read",
+			       err_ret));
+			sd_err(("%s:Disabling rxchain and fire it with PIO\n",
+			       __FUNCTION__));
+			sd->use_rxchain = FALSE;
+			pkt = pprev;
+			lft_len = ttl_len;
+		} else if (!fifo) {
+			addr = addr + ttl_len - lft_len - dma_len;
+		}
 	}
 
-	/* Release host controller */
-	sdio_release_host(gInstance->func[func]);
+	/* PIO mode */
+	if (0 != lft_len) {
+		/* Claim host controller */
+		sdio_claim_host(gInstance->func[func]);
+		for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) {
+			uint8 *buf = (uint8*)PKTDATA(sd->osh, pnext) +
+				xfred_len;
+			pkt_len = PKTLEN(sd->osh, pnext);
+			if (0 != xfred_len) {
+				pkt_len -= xfred_len;
+				xfred_len = 0;
+			}
+			pkt_len = (pkt_len + 3) & 0xFFFFFFFC;
+#ifdef CONFIG_MMC_MSM7X00A
+			if ((pkt_len % 64) == 32) {
+				sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__));
+				pkt_len += 32;
+			}
+#endif /* CONFIG_MMC_MSM7X00A */
+
+			if ((write) && (!fifo))
+				err_ret = sdio_memcpy_toio(
+						gInstance->func[func],
+						addr, buf, pkt_len);
+			else if (write)
+				err_ret = sdio_memcpy_toio(
+						gInstance->func[func],
+						addr, buf, pkt_len);
+			else if (fifo)
+				err_ret = sdio_readsb(
+						gInstance->func[func],
+						buf, addr, pkt_len);
+			else
+				err_ret = sdio_memcpy_fromio(
+						gInstance->func[func],
+						buf, addr, pkt_len);
+
+			if (err_ret)
+				sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=%d\n",
+				       __FUNCTION__,
+				       (write) ? "TX" : "RX",
+				       pnext, SGCount, addr, pkt_len, err_ret));
+			else
+				sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n",
+					__FUNCTION__,
+					(write) ? "TX" : "RX",
+					pnext, SGCount, addr, pkt_len));
+
+			if (!fifo)
+				addr += pkt_len;
+			SGCount ++;
+		}
+		sdio_release_host(gInstance->func[func]);
+	}
 
 	sd_trace(("%s: Exit\n", __FUNCTION__));
 	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
index 30c7fd7..1bb1511 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/bcmdhd/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 309548 2012-01-20 01:13:08Z $
+ * $Id: bcmsdh_sdmmc_linux.c 312783 2012-02-03 22:53:56Z $
  */
 
 #include <typedefs.h>
@@ -198,8 +198,9 @@
 
 static int bcmsdh_sdmmc_resume(struct device *pdev)
 {
+#if defined(OOB_INTR_ONLY)
 	struct sdio_func *func = dev_to_sdio_func(pdev);
-
+#endif
 	sd_trace(("%s Enter\n", __FUNCTION__));
 	dhd_mmc_suspend = FALSE;
 #if defined(OOB_INTR_ONLY)
@@ -217,13 +218,14 @@
 };
 #endif  /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
 
-
+#if defined(BCMLXSDMMC)
 static struct semaphore *notify_semaphore = NULL;
 
 static int dummy_probe(struct sdio_func *func,
                               const struct sdio_device_id *id)
 {
-	up(notify_semaphore);
+	if (notify_semaphore)
+		up(notify_semaphore);
 	return 0;
 }
 
@@ -249,6 +251,8 @@
 	sdio_unregister_driver(&dummy_sdmmc_driver);
 }
 
+#endif /* defined(BCMLXSDMMC) */
+
 static struct sdio_driver bcmsdh_sdmmc_driver = {
 	.probe		= bcmsdh_sdmmc_probe,
 	.remove		= bcmsdh_sdmmc_remove,
diff --git a/drivers/net/wireless/bcmdhd/bcmutils.c b/drivers/net/wireless/bcmdhd/bcmutils.c
index 32ac069..0d92efc 100644
--- a/drivers/net/wireless/bcmdhd/bcmutils.c
+++ b/drivers/net/wireless/bcmdhd/bcmutils.c
@@ -20,7 +20,7 @@
  *      Notwithstanding the above, under no circumstances may you combine this
  * 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: bcmutils.c 309397 2012-01-19 15:36:59Z $
+ * $Id: bcmutils.c 312855 2012-02-04 02:01:18Z $
  */
 
 #include <bcm_cfg.h>
@@ -174,6 +174,10 @@
 		len = PKTLEN(osh, p);
 		if (len > 128) {
 			pktdata = (uint8 *)PKTDATA(osh, p);	/* starting address of data */
+			/* Check for page boundary straddle (2048B) */
+			if (((uintptr)pktdata & ~0x7ff) != ((uintptr)(pktdata+len) & ~0x7ff))
+				cnt++;
+
 			align64 = (uint)((uintptr)pktdata & 0x3f);	/* aligned to 64B */
 			align64 = (64 - align64) & 0x3f;
 			len -= align64;		/* bytes from aligned 64B to end */
@@ -624,7 +628,7 @@
 	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
 		pq->hi_prec--;
 
-	while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
+	while ((pq->q[prec].head == NULL) || ((prec_bmp & (1 << prec)) == 0))
 		if (prec-- == 0)
 			return NULL;
 
diff --git a/drivers/net/wireless/bcmdhd/bcmwifi.c b/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
similarity index 98%
rename from drivers/net/wireless/bcmdhd/bcmwifi.c
rename to drivers/net/wireless/bcmdhd/bcmwifi_channels.c
index bc975e8..0a570f6 100644
--- a/drivers/net/wireless/bcmdhd/bcmwifi.c
+++ b/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
@@ -22,7 +22,7 @@
  *      Notwithstanding the above, under no circumstances may you combine this
  * 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: bcmwifi.c 309193 2012-01-19 00:03:57Z $
+ * $Id: bcmwifi_channels.c 309193 2012-01-19 00:03:57Z $
  */
 
 #include <bcm_cfg.h>
@@ -41,7 +41,13 @@
 #define ASSERT(exp)
 #endif
 #endif 
+
+#ifdef _bcmwifi_c_
+
 #include <bcmwifi.h>
+#else
+#include <bcmwifi_channels.h>
+#endif
 
 #if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL))
 #include <bcmstdlib.h> 	
diff --git a/drivers/net/wireless/bcmdhd/include/bcmwifi.h b/drivers/net/wireless/bcmdhd/bcmwifi_channels.h
similarity index 98%
rename from drivers/net/wireless/bcmdhd/include/bcmwifi.h
rename to drivers/net/wireless/bcmdhd/bcmwifi_channels.h
index f3f593f4..c797047 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmwifi.h
+++ b/drivers/net/wireless/bcmdhd/bcmwifi_channels.h
@@ -23,11 +23,11 @@
  * 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: bcmwifi.h 309193 2012-01-19 00:03:57Z $
+ * $Id: bcmwifi_channels.h 309193 2012-01-19 00:03:57Z $
  */
 
-#ifndef	_bcmwifi_h_
-#define	_bcmwifi_h_
+#ifndef	_bcmwifi_channels_h_
+#define	_bcmwifi_channels_h_
 
 
 
diff --git a/drivers/net/wireless/bcmdhd/bcmwifi_rates.h b/drivers/net/wireless/bcmdhd/bcmwifi_rates.h
new file mode 100644
index 0000000..9896b23
--- /dev/null
+++ b/drivers/net/wireless/bcmdhd/bcmwifi_rates.h
@@ -0,0 +1,306 @@
+/*
+ * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ * 
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ * 
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ * 
+ *      Notwithstanding the above, under no circumstances may you combine this
+ * 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: bcmwifi_rates.h 252708 2011-04-12 06:45:56Z $
+ */
+
+#ifndef _bcmwifi_rates_h_
+#define _bcmwifi_rates_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif 
+
+
+#define WL_RATESET_SZ_DSSS		4
+#define WL_RATESET_SZ_OFDM		8
+#define WL_RATESET_SZ_HT_MCS	8
+#define WL_RATESET_SZ_VHT_MCS	10
+
+#define WL_TX_CHAINS_MAX	3
+
+#define WL_RATE_DISABLED		(-128) 
+
+
+typedef enum wl_tx_bw {
+	WL_TX_BW_20,
+	WL_TX_BW_40,
+	WL_TX_BW_80,
+	WL_TX_BW_20IN40,
+	WL_TX_BW_20IN80,
+	WL_TX_BW_40IN80,
+	WL_TX_BW_ALL
+} wl_tx_bw_t;
+
+
+
+typedef enum wl_tx_mode {
+	WL_TX_MODE_NONE,
+	WL_TX_MODE_STBC,
+	WL_TX_MODE_CDD,
+	WL_TX_MODE_SDM
+} wl_tx_mode_t;
+
+
+
+typedef enum wl_tx_chains {
+	WL_TX_CHAINS_1 = 1,
+	WL_TX_CHAINS_2,
+	WL_TX_CHAINS_3
+} wl_tx_chains_t;
+
+
+
+typedef enum wl_tx_nss {
+	WL_TX_NSS_1 = 1,
+	WL_TX_NSS_2,
+	WL_TX_NSS_3
+} wl_tx_nss_t;
+
+
+typedef enum clm_rates {
+	
+
+	
+	WL_RATE_1X1_DSSS_1         = 0,
+	WL_RATE_1X1_DSSS_2         = 1,
+	WL_RATE_1X1_DSSS_5_5       = 2,
+	WL_RATE_1X1_DSSS_11        = 3,
+
+	WL_RATE_1X1_OFDM_6         = 4,
+	WL_RATE_1X1_OFDM_9         = 5,
+	WL_RATE_1X1_OFDM_12        = 6,
+	WL_RATE_1X1_OFDM_18        = 7,
+	WL_RATE_1X1_OFDM_24        = 8,
+	WL_RATE_1X1_OFDM_36        = 9,
+	WL_RATE_1X1_OFDM_48        = 10,
+	WL_RATE_1X1_OFDM_54        = 11,
+
+	WL_RATE_1X1_MCS0           = 12,
+	WL_RATE_1X1_MCS1           = 13,
+	WL_RATE_1X1_MCS2           = 14,
+	WL_RATE_1X1_MCS3           = 15,
+	WL_RATE_1X1_MCS4           = 16,
+	WL_RATE_1X1_MCS5           = 17,
+	WL_RATE_1X1_MCS6           = 18,
+	WL_RATE_1X1_MCS7           = 19,
+
+	WL_RATE_1X1_VHT0SS1        = 12,
+	WL_RATE_1X1_VHT1SS1        = 13,
+	WL_RATE_1X1_VHT2SS1        = 14,
+	WL_RATE_1X1_VHT3SS1        = 15,
+	WL_RATE_1X1_VHT4SS1        = 16,
+	WL_RATE_1X1_VHT5SS1        = 17,
+	WL_RATE_1X1_VHT6SS1        = 18,
+	WL_RATE_1X1_VHT7SS1        = 19,
+	WL_RATE_1X1_VHT8SS1        = 20,
+	WL_RATE_1X1_VHT9SS1        = 21,
+
+
+	
+
+	
+	WL_RATE_1X2_DSSS_1         = 22,
+	WL_RATE_1X2_DSSS_2         = 23,
+	WL_RATE_1X2_DSSS_5_5       = 24,
+	WL_RATE_1X2_DSSS_11        = 25,
+
+	WL_RATE_1X2_CDD_OFDM_6     = 26,
+	WL_RATE_1X2_CDD_OFDM_9     = 27,
+	WL_RATE_1X2_CDD_OFDM_12    = 28,
+	WL_RATE_1X2_CDD_OFDM_18    = 29,
+	WL_RATE_1X2_CDD_OFDM_24    = 30,
+	WL_RATE_1X2_CDD_OFDM_36    = 31,
+	WL_RATE_1X2_CDD_OFDM_48    = 32,
+	WL_RATE_1X2_CDD_OFDM_54    = 33,
+
+	WL_RATE_1X2_CDD_MCS0       = 34,
+	WL_RATE_1X2_CDD_MCS1       = 35,
+	WL_RATE_1X2_CDD_MCS2       = 36,
+	WL_RATE_1X2_CDD_MCS3       = 37,
+	WL_RATE_1X2_CDD_MCS4       = 38,
+	WL_RATE_1X2_CDD_MCS5       = 39,
+	WL_RATE_1X2_CDD_MCS6       = 40,
+	WL_RATE_1X2_CDD_MCS7       = 41,
+
+	WL_RATE_1X2_VHT0SS1        = 34,
+	WL_RATE_1X2_VHT1SS1        = 35,
+	WL_RATE_1X2_VHT2SS1        = 36,
+	WL_RATE_1X2_VHT3SS1        = 37,
+	WL_RATE_1X2_VHT4SS1        = 38,
+	WL_RATE_1X2_VHT5SS1        = 39,
+	WL_RATE_1X2_VHT6SS1        = 40,
+	WL_RATE_1X2_VHT7SS1        = 41,
+	WL_RATE_1X2_VHT8SS1        = 42,
+	WL_RATE_1X2_VHT9SS1        = 43,
+
+	
+	WL_RATE_2X2_STBC_MCS0      = 44,
+	WL_RATE_2X2_STBC_MCS1      = 45,
+	WL_RATE_2X2_STBC_MCS2      = 46,
+	WL_RATE_2X2_STBC_MCS3      = 47,
+	WL_RATE_2X2_STBC_MCS4      = 48,
+	WL_RATE_2X2_STBC_MCS5      = 49,
+	WL_RATE_2X2_STBC_MCS6      = 50,
+	WL_RATE_2X2_STBC_MCS7      = 51,
+
+	WL_RATE_2X2_STBC_VHT0SS1   = 44,
+	WL_RATE_2X2_STBC_VHT1SS1   = 45,
+	WL_RATE_2X2_STBC_VHT2SS1   = 46,
+	WL_RATE_2X2_STBC_VHT3SS1   = 47,
+	WL_RATE_2X2_STBC_VHT4SS1   = 48,
+	WL_RATE_2X2_STBC_VHT5SS1   = 49,
+	WL_RATE_2X2_STBC_VHT6SS1   = 50,
+	WL_RATE_2X2_STBC_VHT7SS1   = 51,
+	WL_RATE_2X2_STBC_VHT8SS1   = 52,
+	WL_RATE_2X2_STBC_VHT9SS1   = 53,
+
+	WL_RATE_2X2_SDM_MCS8       = 54,
+	WL_RATE_2X2_SDM_MCS9       = 55,
+	WL_RATE_2X2_SDM_MCS10      = 56,
+	WL_RATE_2X2_SDM_MCS11      = 57,
+	WL_RATE_2X2_SDM_MCS12      = 58,
+	WL_RATE_2X2_SDM_MCS13      = 59,
+	WL_RATE_2X2_SDM_MCS14      = 60,
+	WL_RATE_2X2_SDM_MCS15      = 61,
+
+	WL_RATE_2X2_VHT0SS2        = 54,
+	WL_RATE_2X2_VHT1SS2        = 55,
+	WL_RATE_2X2_VHT2SS2        = 56,
+	WL_RATE_2X2_VHT3SS2        = 57,
+	WL_RATE_2X2_VHT4SS2        = 58,
+	WL_RATE_2X2_VHT5SS2        = 59,
+	WL_RATE_2X2_VHT6SS2        = 60,
+	WL_RATE_2X2_VHT7SS2        = 61,
+	WL_RATE_2X2_VHT8SS2        = 62,
+	WL_RATE_2X2_VHT9SS2        = 63,
+
+
+	
+
+	
+	WL_RATE_1X3_DSSS_1         = 64,
+	WL_RATE_1X3_DSSS_2         = 65,
+	WL_RATE_1X3_DSSS_5_5       = 66,
+	WL_RATE_1X3_DSSS_11        = 67,
+
+	WL_RATE_1X3_CDD_OFDM_6     = 68,
+	WL_RATE_1X3_CDD_OFDM_9     = 69,
+	WL_RATE_1X3_CDD_OFDM_12    = 70,
+	WL_RATE_1X3_CDD_OFDM_18    = 71,
+	WL_RATE_1X3_CDD_OFDM_24    = 72,
+	WL_RATE_1X3_CDD_OFDM_36    = 73,
+	WL_RATE_1X3_CDD_OFDM_48    = 74,
+	WL_RATE_1X3_CDD_OFDM_54    = 75,
+
+	WL_RATE_1X3_CDD_MCS0       = 76,
+	WL_RATE_1X3_CDD_MCS1       = 77,
+	WL_RATE_1X3_CDD_MCS2       = 78,
+	WL_RATE_1X3_CDD_MCS3       = 79,
+	WL_RATE_1X3_CDD_MCS4       = 80,
+	WL_RATE_1X3_CDD_MCS5       = 81,
+	WL_RATE_1X3_CDD_MCS6       = 82,
+	WL_RATE_1X3_CDD_MCS7       = 83,
+
+	WL_RATE_1X3_VHT0SS1        = 76,
+	WL_RATE_1X3_VHT1SS1        = 77,
+	WL_RATE_1X3_VHT2SS1        = 78,
+	WL_RATE_1X3_VHT3SS1        = 79,
+	WL_RATE_1X3_VHT4SS1        = 80,
+	WL_RATE_1X3_VHT5SS1        = 81,
+	WL_RATE_1X3_VHT6SS1        = 82,
+	WL_RATE_1X3_VHT7SS1        = 83,
+	WL_RATE_1X3_VHT8SS1        = 84,
+	WL_RATE_1X3_VHT9SS1        = 85,
+
+	
+	WL_RATE_2X3_STBC_MCS0      = 86,
+	WL_RATE_2X3_STBC_MCS1      = 87,
+	WL_RATE_2X3_STBC_MCS2      = 88,
+	WL_RATE_2X3_STBC_MCS3      = 89,
+	WL_RATE_2X3_STBC_MCS4      = 90,
+	WL_RATE_2X3_STBC_MCS5      = 91,
+	WL_RATE_2X3_STBC_MCS6      = 92,
+	WL_RATE_2X3_STBC_MCS7      = 93,
+
+	WL_RATE_2X3_STBC_VHT0SS1   = 86,
+	WL_RATE_2X3_STBC_VHT1SS1   = 87,
+	WL_RATE_2X3_STBC_VHT2SS1   = 88,
+	WL_RATE_2X3_STBC_VHT3SS1   = 89,
+	WL_RATE_2X3_STBC_VHT4SS1   = 90,
+	WL_RATE_2X3_STBC_VHT5SS1   = 91,
+	WL_RATE_2X3_STBC_VHT6SS1   = 92,
+	WL_RATE_2X3_STBC_VHT7SS1   = 93,
+	WL_RATE_2X3_STBC_VHT8SS1   = 94,
+	WL_RATE_2X3_STBC_VHT9SS1   = 95,
+
+	WL_RATE_2X3_SDM_MCS8       = 96,
+	WL_RATE_2X3_SDM_MCS9       = 97,
+	WL_RATE_2X3_SDM_MCS10      = 98,
+	WL_RATE_2X3_SDM_MCS11      = 99,
+	WL_RATE_2X3_SDM_MCS12      = 100,
+	WL_RATE_2X3_SDM_MCS13      = 101,
+	WL_RATE_2X3_SDM_MCS14      = 102,
+	WL_RATE_2X3_SDM_MCS15      = 103,
+
+	WL_RATE_2X3_VHT0SS2        = 96,
+	WL_RATE_2X3_VHT1SS2        = 97,
+	WL_RATE_2X3_VHT2SS2        = 98,
+	WL_RATE_2X3_VHT3SS2        = 99,
+	WL_RATE_2X3_VHT4SS2        = 100,
+	WL_RATE_2X3_VHT5SS2        = 101,
+	WL_RATE_2X3_VHT6SS2        = 102,
+	WL_RATE_2X3_VHT7SS2        = 103,
+	WL_RATE_2X3_VHT8SS2        = 104,
+	WL_RATE_2X3_VHT9SS2        = 105,
+
+	
+	WL_RATE_3X3_SDM_MCS16      = 106,
+	WL_RATE_3X3_SDM_MCS17      = 107,
+	WL_RATE_3X3_SDM_MCS18      = 108,
+	WL_RATE_3X3_SDM_MCS19      = 109,
+	WL_RATE_3X3_SDM_MCS20      = 110,
+	WL_RATE_3X3_SDM_MCS21      = 111,
+	WL_RATE_3X3_SDM_MCS22      = 112,
+	WL_RATE_3X3_SDM_MCS23      = 113,
+
+	WL_RATE_3X3_VHT0SS3        = 106,
+	WL_RATE_3X3_VHT1SS3        = 107,
+	WL_RATE_3X3_VHT2SS3        = 108,
+	WL_RATE_3X3_VHT3SS3        = 109,
+	WL_RATE_3X3_VHT4SS3        = 110,
+	WL_RATE_3X3_VHT5SS3        = 111,
+	WL_RATE_3X3_VHT6SS3        = 112,
+	WL_RATE_3X3_VHT7SS3        = 113,
+	WL_RATE_3X3_VHT8SS3        = 114,
+	WL_RATE_3X3_VHT9SS3        = 115,
+
+	
+	WL_NUMRATES                = 116
+} clm_rates_t;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif 
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 16d1d35..3c8ca44 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.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: dhd.h 309548 2012-01-20 01:13:08Z $
+ * $Id: dhd.h 322404 2012-03-20 20:41:32Z $
  */
 
 /****************
@@ -63,7 +63,6 @@
 struct dhd_bus;
 struct dhd_prot;
 struct dhd_info;
-struct dhd_cmn;
 
 /* The level of bus communication with the dongle */
 enum dhd_bus_state {
@@ -162,7 +161,6 @@
 	struct dhd_bus *bus;	/* Bus module handle */
 	struct dhd_prot *prot;	/* Protocol module handle */
 	struct dhd_info  *info; /* Info module handle */
-	struct dhd_cmn	*cmn;	/* dhd_common module handle */
 
 	/* Internal dhd items */
 	bool up;		/* Driver up/down (to OS) */
@@ -213,6 +211,7 @@
 	int in_suspend;			/* flag set to 1 when early suspend called */
 #ifdef PNO_SUPPORT
 	int pno_enable;                 /* pno status : "1" is pno enable */
+	int pno_suspend;		/* pno suspend status : "1" is pno suspended */
 #endif /* PNO_SUPPORT */
 	int dtim_skip;         /* dtim skip , default 0 means wake each dtim */
 
@@ -249,11 +248,6 @@
 	struct reorder_info *reorder_bufs[WLHOST_REORDERDATA_MAXFLOWS];
 } dhd_pub_t;
 
-typedef struct dhd_cmn {
-	osl_t *osh;		/* OSL handle */
-	dhd_pub_t *dhd;
-} dhd_cmn_t;
-
 
 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
 
@@ -440,6 +434,7 @@
 extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub);
 extern void dhd_os_sdlock_eventq(dhd_pub_t * pub);
 extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub);
+extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret);
 
 #ifdef PNO_SUPPORT
 extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
@@ -463,7 +458,6 @@
 
 extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
 extern bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd);
-extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret);
 
 #ifdef DHD_DEBUG
 extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size);
@@ -495,9 +489,9 @@
 extern int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set,
                             int ifindex);
 
-extern struct dhd_cmn *dhd_common_init(osl_t *osh);
-extern void dhd_common_deinit(dhd_pub_t *dhd_pub, dhd_cmn_t *sa_cmn);
+extern void dhd_common_init(osl_t *osh);
 
+extern int dhd_do_driver_init(struct net_device *net);
 extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle,
 	char *name, uint8 *mac_addr, uint32 flags, uint8 bssidx);
 extern void dhd_del_if(struct dhd_info *dhd, int ifidx);
@@ -522,6 +516,7 @@
 extern int dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size);
 extern void dhd_print_buf(void *pbuf, int len, int bytes_per_line);
 extern bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf);
+extern uint dhd_bus_chip_id(dhd_pub_t *dhdp);
 
 #if defined(KEEP_ALIVE)
 extern int dhd_keep_alive_onoff(dhd_pub_t *dhd);
@@ -555,6 +550,7 @@
 extern uint wl_msg_level;
 #endif /* defined(DHD_DEBUG) */
 
+extern uint dhd_slpauto;
 
 /* Use interrupts */
 extern uint dhd_intr;
@@ -749,6 +745,24 @@
 extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar);
 extern void dhd_wait_event_wakeup(dhd_pub_t*dhd);
 
+#define IFLOCK_INIT(lock)       *lock = 0
+#define IFLOCK(lock)    while (InterlockedCompareExchange((lock), 1, 0))	\
+	NdisStallExecution(1);
+#define IFUNLOCK(lock)  InterlockedExchange((lock), 0)
+#define IFLOCK_FREE(lock)
+
+#ifdef PNO_SUPPORT
+extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
+extern int dhd_pnoenable(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,
+                       ushort  scan_fr, int pno_repeat, int pno_freq_expo_max);
+extern int dhd_pno_get_status(dhd_pub_t *dhd);
+extern int dhd_pno_set_add(dhd_pub_t *dhd, wl_pfn_t *netinfo, int nssid, ushort scan_fr,
+	ushort slowscan_fr, uint8 pno_repeat, uint8 pno_freq_expo_max, int16 flags);
+extern int dhd_pno_cfg(dhd_pub_t *dhd, wl_pfn_cfg_t *pcfg);
+extern int dhd_pno_suspend(dhd_pub_t *dhd, int pfn_suspend);
+#endif /* PNO_SUPPORT */
 #ifdef ARP_OFFLOAD_SUPPORT
 #define MAX_IPV4_ENTRIES	8
 /* dhd_commn arp offload wrapers */
diff --git a/drivers/net/wireless/bcmdhd/dhd_bta.c b/drivers/net/wireless/bcmdhd/dhd_bta.c
index 6b782ea..15c605e 100644
--- a/drivers/net/wireless/bcmdhd/dhd_bta.c
+++ b/drivers/net/wireless/bcmdhd/dhd_bta.c
@@ -1,9 +1,9 @@
 /*
  * BT-AMP support routines
  *
- * Copyright (C) 1999-2011, Broadcom Corporation
+ * Copyright (C) 1999-2012, Broadcom Corporation
  * 
- *         Unless you and Broadcom execute a separate written software license
+ *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
  * under the terms of the GNU General Public License version 2 (the "GPL"),
  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
@@ -21,8 +21,11 @@
  * 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_bta.c,v 1.10.4.2 2010-12-22 23:47:23 Exp $
+ * $Id: dhd_bta.c 303834 2011-12-20 06:17:39Z $
  */
+#ifndef WLBTAMP
+#error "WLBTAMP is not defined"
+#endif	/* WLBTAMP */
 
 #include <typedefs.h>
 #include <osl.h>
@@ -99,7 +102,7 @@
 			int ifidx;
 
 			PKTPULL(pub->osh, pkt, dhd_bus_hdrlen(pub->bus));
-			dhd_prot_hdrpull(pub, &ifidx, pkt);
+			dhd_prot_hdrpull(pub, &ifidx, pkt, NULL, NULL);
 
 			if (PKTLEN(pub->osh, pkt) >= RFC1042_HDR_LEN) {
 				struct ether_header *eh =
diff --git a/drivers/net/wireless/bcmdhd/dhd_bus.h b/drivers/net/wireless/bcmdhd/dhd_bus.h
index 5eb9149..3626771 100644
--- a/drivers/net/wireless/bcmdhd/dhd_bus.h
+++ b/drivers/net/wireless/bcmdhd/dhd_bus.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: dhd_bus.h 309567 2012-01-20 01:40:54Z $
+ * $Id: dhd_bus.h 313456 2012-02-07 22:03:40Z $
  */
 
 #ifndef _dhd_bus_h_
@@ -97,6 +97,11 @@
 extern void *dhd_bus_txq(struct dhd_bus *bus);
 extern uint dhd_bus_hdrlen(struct dhd_bus *bus);
 
+
+#define DHD_SET_BUS_STATE_DOWN(_bus)  do { \
+	(_bus)->dhd->busstate = DHD_BUS_DOWN; \
+} while (0)
+
 /* Register a dummy SDIO client driver in order to be notified of new SDIO device */
 extern int dhd_bus_reg_sdio_notify(void* semaphore);
 extern void dhd_bus_unreg_sdio_notify(void);
diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c
index 60c7fe4..3b03cb6 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cdc.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_cdc.c 304241 2011-12-21 16:43:50Z $
+ * $Id: dhd_cdc.c 325074 2012-03-31 21:24:57Z $
  *
  * BDC is like CDC, except it includes a header for data packets to convey
  * packet priority over the bus, and flags (e.g. to indicate checksum status
@@ -53,7 +53,7 @@
 				 * defined in dhd_sdio.c (amount of header tha might be added)
 				 * plus any space that might be needed for alignment padding.
 				 */
-#define ROUND_UP_MARGIN	2048 	/* Biggest SDIO block size possible for
+#define ROUND_UP_MARGIN	2048	/* Biggest SDIO block size possible for
 				 * round off at the end of buffer
 				 */
 
@@ -284,11 +284,26 @@
 	dhd_prot_t *prot = dhd->prot;
 	int ret = -1;
 	uint8 action;
+#if defined(NDIS630)
+	bool acquired = FALSE;
+#endif
 
 	if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) {
 		DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
 		goto done;
 	}
+#if defined(NDIS630)
+	if (dhd_os_proto_block(dhd))
+	{
+		acquired = TRUE;
+	}
+	else
+	{
+		/* attempt to acquire protocol mutex timed out. */
+		ret = -1;
+		return ret;
+	}
+#endif /* NDIS630 */
 
 	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
@@ -339,6 +354,10 @@
 	prot->pending = FALSE;
 
 done:
+#if defined(NDIS630)
+	if (acquired)
+	   dhd_os_proto_unblock(dhd);
+#endif
 	return ret;
 }
 
@@ -795,7 +814,6 @@
 	uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p));
 	uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p));
 
-	/* no lookup necessary, only if this packet belongs to STA interface */
 	if (((ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_STA) ||
 		ETHER_ISMULTI(dstn) ||
 		(ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_P2P_CLIENT)) &&
@@ -1300,6 +1318,17 @@
 			memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN);
 		pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN);
 	}
+	else if (action == eWLFC_MAC_ENTRY_ACTION_UPDATE) {
+		entry->occupied = 1;
+		entry->state = WLFC_STATE_OPEN;
+		entry->requested_credit = 0;
+		entry->interface_id = ifid;
+		entry->iftype = iftype;
+		entry->ac_bitmap = 0xff; /* update this when handling APSD */
+		/* for an interface entry we may not care about the MAC address */
+		if (ea != NULL)
+			memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN);
+	}
 	else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) {
 		entry->occupied = 0;
 		entry->state = WLFC_STATE_CLOSE;
@@ -1396,41 +1425,13 @@
 }
 
 int
-dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx)
+_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac,
+    dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx)
 {
-	int ac;
-	int credit;
-	uint8 ac_fifo_credit_spent;
-	uint8 needs_hdr;
 	uint32 hslot;
-	void* p;
 	int	rc;
-	athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
-	wlfc_mac_descriptor_t* mac_entry;
-
-	if ((state == NULL) ||
-		(fcommit == NULL)) {
-		WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__));
-		return BCME_BADARG;
-	}
 
 	/*
-	Commit packets for regular AC traffic. Higher priority first.
-
-	-NOTE:
-	If the bus between the host and firmware is overwhelmed by the
-	traffic from host, it is possible that higher priority traffic
-	starves the lower priority queue. If that occurs often, we may
-	have to employ weighted round-robin or ucode scheme to avoid
-	low priority packet starvation.
-	*/
-	for (ac = AC_COUNT; ac >= 0; ac--) {
-		for (credit = 0; credit < ctx->FIFO_credit[ac];) {
-			p = _dhd_wlfc_deque_delayedq(ctx, ac, &ac_fifo_credit_spent, &needs_hdr,
-				&mac_entry);
-			if (p == NULL)
-				break;
-			/*
 		if ac_fifo_credit_spent = 0
 
 		This packet will not count against the FIFO credit.
@@ -1443,77 +1444,254 @@
 		This is a normal packet and it counts against the FIFO
 		credit count.
 	*/
-			DHD_PKTTAG_SETCREDITCHECK(PKTTAG(p), ac_fifo_credit_spent);
-			rc = _dhd_wlfc_pretx_pktprocess(ctx, mac_entry, p, needs_hdr, &hslot);
+	DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent);
+	rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, commit_info->p,
+	     commit_info->needs_hdr, &hslot);
 
 	if (rc == BCME_OK)
-				rc = fcommit(commit_ctx, p);
+		rc = fcommit(commit_ctx, commit_info->p);
 	else
 		ctx->stats.generic_error++;
 
 	if (rc == BCME_OK) {
 		ctx->stats.pkt2bus++;
-				if (ac_fifo_credit_spent) {
+		if (commit_info->ac_fifo_credit_spent) {
 			ctx->stats.sendq_pkts[ac]++;
 			WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac);
-					/*
-					1 FIFO credit has been spent by sending this packet
-					to the device.
-					*/
-					credit++;
 		}
 	}
 	else {
-				/* bus commit has failed, rollback. */
-				rc = _dhd_wlfc_rollback_packet_toq(ctx,
-					p,
 		/*
+		   bus commit has failed, rollback.
 		   - remove wl-header for a delayed packet
 		   - save wl-header header for suppressed packets
 		*/
-					(needs_hdr ? eWLFC_PKTTYPE_DELAYED :
-					eWLFC_PKTTYPE_SUPPRESSED),
-					hslot);
+		rc = _dhd_wlfc_rollback_packet_toq(ctx,	commit_info->p,
+		     (commit_info->pkt_type), hslot);
 		if (rc != BCME_OK)
 			ctx->stats.rollback_failed++;
-}
+
+		rc = BCME_ERROR;
 	}
-		ctx->FIFO_credit[ac] -= credit;
-		/* packets from SENDQ are fresh and they'd need header */
-		needs_hdr = 1;
+
+	return rc;
+}
+
+int
+dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx)
+{
+	int ac;
+	int credit;
+	int rc;
+	dhd_wlfc_commit_info_t  commit_info;
+	athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+	int credit_count = 0;
+	int bus_retry_count = 0;
+	uint8 ac_available = 0;  /* Bitmask for 4 ACs + BC/MC */
+
+	if ((state == NULL) ||
+		(fcommit == NULL)) {
+		WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__));
+		return BCME_BADARG;
+	}
+
+	memset(&commit_info, 0, sizeof(commit_info));
+
+	/*
+	Commit packets for regular AC traffic. Higher priority first.
+	First, use up FIFO credits available to each AC. Based on distribution
+	and credits left, borrow from other ACs as applicable
+
+	-NOTE:
+	If the bus between the host and firmware is overwhelmed by the
+	traffic from host, it is possible that higher priority traffic
+	starves the lower priority queue. If that occurs often, we may
+	have to employ weighted round-robin or ucode scheme to avoid
+	low priority packet starvation.
+	*/
+
+	for (ac = AC_COUNT; ac >= 0; ac--) {
+
+		int initial_credit_count = ctx->FIFO_credit[ac];
+
 		for (credit = 0; credit < ctx->FIFO_credit[ac];) {
-			p = _dhd_wlfc_deque_sendq(ctx, ac, &ac_fifo_credit_spent);
-			if (p == NULL)
+			commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
+			                &(commit_info.ac_fifo_credit_spent),
+			                &(commit_info.needs_hdr),
+			                &(commit_info.mac_entry));
+
+			if (commit_info.p == NULL)
 				break;
 
-			DHD_PKTTAG_SETCREDITCHECK(PKTTAG(p), ac_fifo_credit_spent);
-			rc = _dhd_wlfc_pretx_pktprocess(ctx, NULL, p, needs_hdr, &hslot);
-			if (rc == BCME_OK)
-				rc = fcommit(commit_ctx, p);
-			else
-				ctx->stats.generic_error++;
+			commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
+				eWLFC_PKTTYPE_SUPPRESSED;
 
+			rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+			     fcommit, commit_ctx);
+
+			/* Bus commits may fail (e.g. flow control); abort after retries */
 			if (rc == BCME_OK) {
-				ctx->stats.pkt2bus++;
-				if (ac_fifo_credit_spent) {
-					WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac);
-					ctx->stats.sendq_pkts[ac]++;
+				if (commit_info.ac_fifo_credit_spent) {
 					credit++;
 				}
 			}
 			else {
-				/* bus commit has failed, rollback. */
-				rc = _dhd_wlfc_rollback_packet_toq(ctx,
-					p,
-					/* remove wl-header while rolling back */
-					eWLFC_PKTTYPE_NEW,
-					hslot);
-				if (rc != BCME_OK)
-					ctx->stats.rollback_failed++;
+				bus_retry_count++;
+				if (bus_retry_count >= BUS_RETRIES) {
+					DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n"));
+					ctx->FIFO_credit[ac] -= credit;
+					return rc;
+				}
 			}
 		}
+
 		ctx->FIFO_credit[ac] -= credit;
+
+		/* packets from SENDQ are fresh and they'd need header and have no MAC entry */
+		commit_info.needs_hdr = 1;
+		commit_info.mac_entry = NULL;
+		commit_info.pkt_type = eWLFC_PKTTYPE_NEW;
+
+		for (credit = 0; credit < ctx->FIFO_credit[ac];) {
+			commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac,
+			                &(commit_info.ac_fifo_credit_spent));
+			if (commit_info.p == NULL)
+				break;
+
+			rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+			     fcommit, commit_ctx);
+
+			/* Bus commits may fail (e.g. flow control); abort after retries */
+			if (rc == BCME_OK) {
+				if (commit_info.ac_fifo_credit_spent) {
+					credit++;
+				}
+			}
+			else {
+				bus_retry_count++;
+				if (bus_retry_count >= BUS_RETRIES) {
+					DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n"));
+					ctx->FIFO_credit[ac] -= credit;
+					return rc;
+				}
+			}
+		}
+
+		ctx->FIFO_credit[ac] -= credit;
+
+		/* If no credits were used, the queue is idle and can be re-used
+		   Note that resv credits cannot be borrowed
+		   */
+		if (initial_credit_count == ctx->FIFO_credit[ac]) {
+			ac_available |= (1 << ac);
+			credit_count += ctx->FIFO_credit[ac];
+		}
 	}
+
+	/* We borrow only for AC_BE and only if no other traffic seen for DEFER_PERIOD
+
+	   Note that (ac_available & WLFC_AC_BE_TRAFFIC_ONLY) is done to:
+	   a) ignore BC/MC for deferring borrow
+	   b) ignore AC_BE being available along with other ACs
+		  (this should happen only for pure BC/MC traffic)
+
+	   i.e. AC_VI, AC_VO, AC_BK all MUST be available (i.e. no traffic) and
+	   we do not care if AC_BE and BC/MC are available or not
+	   */
+	if ((ac_available & WLFC_AC_BE_TRAFFIC_ONLY) == WLFC_AC_BE_TRAFFIC_ONLY) {
+
+		if (ctx->allow_credit_borrow) {
+			ac = 1;  /* Set ac to AC_BE and borrow credits */
+		}
+		else {
+			int delta;
+			int curr_t = OSL_SYSUPTIME();
+
+			if (curr_t > ctx->borrow_defer_timestamp)
+				delta = curr_t - ctx->borrow_defer_timestamp;
+			else
+				delta = 0xffffffff + curr_t - ctx->borrow_defer_timestamp;
+
+			if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) {
+				/* Reset borrow but defer to next iteration (defensive borrowing) */
+				ctx->allow_credit_borrow = TRUE;
+				ctx->borrow_defer_timestamp = 0;
+			}
+			return BCME_OK;
+		}
+	}
+	else {
+		/* If we have multiple AC traffic, turn off borrowing, mark time and bail out */
+		ctx->allow_credit_borrow = FALSE;
+		ctx->borrow_defer_timestamp = OSL_SYSUPTIME();
+		return BCME_OK;
+	}
+
+	/* At this point, borrow all credits only for "ac" (which should be set above to AC_BE)
+	   Generically use "ac" only in case we extend to all ACs in future
+	   */
+	for (; (credit_count > 0);) {
+
+		commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
+		                &(commit_info.ac_fifo_credit_spent),
+		                &(commit_info.needs_hdr),
+		                &(commit_info.mac_entry));
+		if (commit_info.p == NULL)
+			break;
+
+		commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
+			eWLFC_PKTTYPE_SUPPRESSED;
+
+		rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+		     fcommit, commit_ctx);
+
+		/* Bus commits may fail (e.g. flow control); abort after retries */
+		if (rc == BCME_OK) {
+			if (commit_info.ac_fifo_credit_spent) {
+				(void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac);
+				credit_count--;
+			}
+		}
+		else {
+			bus_retry_count++;
+			if (bus_retry_count >= BUS_RETRIES) {
+				DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n"));
+				return rc;
+			}
+		}
+	}
+
+	/* packets from SENDQ are fresh and they'd need header and have no MAC entry */
+	commit_info.needs_hdr = 1;
+	commit_info.mac_entry = NULL;
+	commit_info.pkt_type = eWLFC_PKTTYPE_NEW;
+
+	for (; (credit_count > 0);) {
+
+		commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac,
+		                &(commit_info.ac_fifo_credit_spent));
+		if (commit_info.p == NULL)
+			break;
+
+		rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+		     fcommit, commit_ctx);
+
+		/* Bus commits may fail (e.g. flow control); abort after retries */
+		if (rc == BCME_OK) {
+			if (commit_info.ac_fifo_credit_spent) {
+				(void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac);
+				credit_count--;
+			}
+		}
+		else {
+			bus_retry_count++;
+			if (bus_retry_count >= BUS_RETRIES) {
+				DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n"));
+				return rc;
+			}
+		}
+	}
+
 	return BCME_OK;
 }
 
@@ -2266,6 +2444,9 @@
 		return BCME_ERROR;
 	}
 
+#if defined(NDIS630)
+	h->dataOffset = 0;
+#endif
 	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) {
 		DHD_ERROR(("%s: non-BDC packet received, flags = 0x%x\n",
 		           dhd_ifname(dhd, *ifidx), h->flags));
@@ -2285,12 +2466,13 @@
 	PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN);
 #endif /* BDC */
 
+#if !defined(NDIS630)
 	if (PKTLEN(dhd->osh, pktbuf) < (uint32) (h->dataOffset << 2)) {
 		DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__,
 		           PKTLEN(dhd->osh, pktbuf), (h->dataOffset * 4)));
 		return BCME_ERROR;
 	}
-
+#endif
 #ifdef PROP_TXSTATUS
 	if (dhd->wlfc_state &&
 		((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode
@@ -2308,7 +2490,9 @@
 		dhd_os_wlfc_unblock(dhd);
 	}
 #endif /* PROP_TXSTATUS */
-	    PKTPULL(dhd->osh, pktbuf, (h->dataOffset << 2));
+#if !defined(NDIS630)
+		PKTPULL(dhd->osh, pktbuf, (h->dataOffset << 2));
+#endif
 	return 0;
 }
 
@@ -2440,7 +2624,7 @@
 			if (plast == NULL)
 				*pkt = p;
 			else
-				PKTSETNEXT(dhd->osh, plast, p);
+				PKTSETNEXT(osh, plast, p);
 
 			plast = p;
 			pkt_cnt++;
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index afe1e28..84c3335 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/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 304622 2011-12-22 19:51:18Z $
+ * $Id: dhd_common.c 321870 2012-03-17 00:43:35Z $
  */
 #include <typedefs.h>
 #include <osl.h>
@@ -53,6 +53,13 @@
 #include <linux/jiffies.h>
 #endif
 
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+
 #ifdef PROP_TXSTATUS
 #include <wlfc_proto.h>
 #include <dhd_wlfc.h>
@@ -80,10 +87,6 @@
 uint32 dhd_conn_status;
 uint32 dhd_conn_reason;
 
-#define htod32(i) i
-#define htod16(i) i
-#define dtoh32(i) i
-#define dtoh16(i) i
 extern int dhd_iscan_request(void * dhdp, uint16 action);
 extern void dhd_ind_scan_confirm(void *h, bool status);
 extern int dhd_iscan_in_progress(void *h);
@@ -178,25 +181,9 @@
 	{NULL, 0, 0, 0, 0 }
 };
 
-struct dhd_cmn *
+void
 dhd_common_init(osl_t *osh)
 {
-	dhd_cmn_t *cmn;
-
-	/* Init global variables at run-time, not as part of the declaration.
-	 * This is required to support init/de-init of the driver. Initialization
-	 * of globals as part of the declaration results in non-deterministic
-	 * behavior since the value of the globals may be different on the
-	 * first time that the driver is initialized vs subsequent initializations.
-	 */
-	/* Allocate private bus interface state */
-	if (!(cmn = MALLOC(osh, sizeof(dhd_cmn_t)))) {
-		DHD_ERROR(("%s: MALLOC failed\n", __FUNCTION__));
-		return NULL;
-	}
-	memset(cmn, 0, sizeof(dhd_cmn_t));
-	cmn->osh = osh;
-
 #ifdef CONFIG_BCMDHD_FW_PATH
 	bcm_strncpy_s(fw_path, sizeof(fw_path), CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
 #else /* CONFIG_BCMDHD_FW_PATH */
@@ -210,28 +197,6 @@
 #ifdef SOFTAP
 	fw_path2[0] = '\0';
 #endif
-	return cmn;
-}
-
-void
-dhd_common_deinit(dhd_pub_t *dhd_pub, dhd_cmn_t *sa_cmn)
-{
-	osl_t *osh;
-	dhd_cmn_t *cmn;
-
-	if (dhd_pub != NULL)
-		cmn = dhd_pub->cmn;
-	else
-		cmn = sa_cmn;
-
-	if (!cmn)
-		return;
-
-	osh = cmn->osh;
-
-	if (dhd_pub != NULL)
-	dhd_pub->cmn = NULL;
-	MFREE(osh, cmn, sizeof(dhd_cmn_t));
 }
 
 static int
@@ -345,6 +310,11 @@
 
 	case IOV_SVAL(IOV_MSGLEVEL):
 		dhd_msg_level = int_val;
+#ifdef WL_CFG80211
+		/* Enable DHD and WL logs in oneshot */
+		if (dhd_msg_level & DHD_WL_VAL)
+			wl_cfg80211_enable_trace(dhd_msg_level);
+#endif
 		break;
 	case IOV_GVAL(IOV_BCMERRORSTR):
 		bcm_strncpy_s((char *)arg, len, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN);
@@ -1050,11 +1020,16 @@
 		              ((ifevent->is_AP == 0) ? "STA":"AP "),
 		              ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]));
 		(void)ea;
+		if (ifevent->action == WLC_E_IF_CHANGE)
+			dhd_wlfc_interface_event(dhd_pub->info,
+				eWLFC_MAC_ENTRY_ACTION_UPDATE,
+				ifevent->ifidx, ifevent->is_AP, ea);
+		else
+			dhd_wlfc_interface_event(dhd_pub->info,
+				((ifevent->action == WLC_E_IF_ADD) ?
+				eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL),
+				ifevent->ifidx, ifevent->is_AP, ea);
 
-		dhd_wlfc_interface_event(dhd_pub->info,
-			((ifevent->action == WLC_E_IF_ADD) ?
-			eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL),
-			ifevent->ifidx, ifevent->is_AP, ea);
 
 		/* dhd already has created an interface by default, for 0 */
 		if (ifevent->ifidx == 0)
@@ -1086,8 +1061,8 @@
 							return (BCME_ERROR);
 						}
 					}
-			else
-				dhd_del_if(dhd_pub->info, ifevent->ifidx);
+					else if (ifevent->action == WLC_E_IF_DEL)
+						dhd_del_if(dhd_pub->info, ifevent->ifidx);
 		} else {
 #ifndef PROP_TXSTATUS
 			DHD_ERROR(("%s: Invalid ifidx %d for %s\n",
@@ -1107,12 +1082,17 @@
 		htsf_update(dhd_pub->info, event_data);
 		break;
 #endif /* WLMEDIA_HTSF */
+#if defined(NDIS630)
+	case WLC_E_NDIS_LINK:
+		break;
+#else /* defined(NDIS630) && defined(BCMDONGLEHOST) */
 	case WLC_E_NDIS_LINK: {
 		uint32 temp = hton32(WLC_E_LINK);
 
 		memcpy((void *)(&pvt_data->event.event_type), &temp,
 		       sizeof(pvt_data->event.event_type));
 	}
+#endif 
 		/* These are what external supplicant/authenticator wants */
 		/* fall through */
 	case WLC_E_LINK:
@@ -1856,7 +1836,7 @@
 		return FALSE;
 }
 
-#ifdef PNO_SUPPORT
+#if defined(PNO_SUPPORT)
 int
 dhd_pno_clean(dhd_pub_t *dhd)
 {
@@ -2051,7 +2031,7 @@
 		return (dhd->pno_enable);
 }
 
-#endif /* PNO_SUPPORT */
+#endif /* OEM_ANDROID && PNO_SUPPORT */
 
 #if defined(KEEP_ALIVE)
 int dhd_keep_alive_onoff(dhd_pub_t *dhd)
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 1c8437b..498eb4f 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -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: dhd_linux.c 309571 2012-01-20 01:45:10Z $
+ * $Id: dhd_linux.c 324874 2012-03-30 18:29:52Z $
  */
 
 #include <typedefs.h>
@@ -49,6 +49,7 @@
 #include <epivers.h>
 #include <bcmutils.h>
 #include <bcmendian.h>
+#include <bcmdevs.h>
 
 #include <proto/ethernet.h>
 #include <dngl_stats.h>
@@ -190,6 +191,7 @@
 	char			name[IFNAMSIZ+1]; /* linux interface name */
 	uint8			bssidx;			/* bsscfg index for the interface */
 	bool			set_multicast;
+	bool			event2cfg80211;	/* To determine if pass event to cfg80211 */
 } dhd_if_t;
 
 #ifdef WLMEDIA_HTSF
@@ -252,10 +254,8 @@
 
 	tsk_ctl_t	thr_dpc_ctl;
 	tsk_ctl_t	thr_wdt_ctl;
-
-#else
-	bool dhd_tasklet_create;
 #endif /* DHDTHREAD */
+	bool dhd_tasklet_create;
 	tsk_ctl_t	thr_sysioc_ctl;
 
 	/* Wakelocks */
@@ -275,7 +275,7 @@
 	int wakelock_timeout_enable;
 
 	/* Thread to issue ioctl for multicast */
-	bool set_macaddress;
+	unsigned char set_macaddress;
 	struct ether_addr macvalue;
 	wait_queue_head_t ctrl_wait;
 	atomic_t pend_8021x_cnt;
@@ -293,15 +293,19 @@
 	void *rpc_osh;
 	struct timer_list rpcth_timer;
 	bool rpcth_timer_active;
+	bool fdaggr;
 #endif
 } dhd_info_t;
 
+
 /* Definitions to provide path to the firmware and nvram
  * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt"
  */
 char firmware_path[MOD_PARAM_PATHLEN];
 char nvram_path[MOD_PARAM_PATHLEN];
 
+int op_mode = 0;
+module_param(op_mode, int, 0644);
 extern int wl_control_wl_start(struct net_device *dev);
 extern int net_os_send_hang_message(struct net_device *dev);
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -332,6 +336,8 @@
 module_param(dhd_console_ms, uint, 0644);
 #endif /* defined(DHD_DEBUG) */
 
+uint dhd_slpauto = TRUE;
+module_param(dhd_slpauto, uint, 0);
 
 /* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */
 uint dhd_arp_mode = 0xb;
@@ -341,9 +347,11 @@
 uint dhd_arp_enable = TRUE;
 module_param(dhd_arp_enable, uint, 0);
 
+#ifdef PKT_FILTER_SUPPORT
 /* Global Pkt filter enable control */
 uint dhd_pkt_filter_enable = TRUE;
 module_param(dhd_pkt_filter_enable, uint, 0);
+#endif
 
 /*  Pkt filter init setup */
 uint dhd_pkt_filter_init = 0;
@@ -376,6 +384,12 @@
 char iface_name[IFNAMSIZ] = {'\0'};
 module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define BLOCKABLE()	(!in_atomic())
+#else
+#define BLOCKABLE()	(!in_interrupt())
+#endif
+
 /* The following are specific to the SDIO dongle */
 
 /* IOCTL response timeout */
@@ -987,6 +1001,7 @@
 				if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, ifp->bssidx,
 					(void*)dhd_net_attach)) {
 					ifp->state = DHD_IF_NONE;
+					ifp->event2cfg80211 = TRUE;
 					return;
 				}
 #endif
@@ -1098,10 +1113,10 @@
 					continue;
 				}
 #ifdef SOFTAP
-				if (in_ap && dhd->set_macaddress)  {
+				if (in_ap && dhd->set_macaddress == i+1)  {
 					DHD_TRACE(("attempt to set MAC for %s in AP Mode,"
 						"blocked. \n", dhd->iflist[i]->net->name));
-					dhd->set_macaddress = FALSE;
+					dhd->set_macaddress = 0;
 					continue;
 				}
 
@@ -1116,8 +1131,8 @@
 					dhd->iflist[i]->set_multicast = FALSE;
 					_dhd_set_multicast_list(dhd, i);
 				}
-				if (dhd->set_macaddress) {
-					dhd->set_macaddress = FALSE;
+				if (dhd->set_macaddress == i+1) {
+					dhd->set_macaddress = 0;
 					_dhd_set_mac_address(dhd, i, &dhd->macvalue);
 				}
 			}
@@ -1145,7 +1160,7 @@
 
 	ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0);
 	memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN);
-	dhd->set_macaddress = TRUE;
+	dhd->set_macaddress = ifidx+1;
 	up(&dhd->thr_sysioc_ctl.sema);
 
 	return ret;
@@ -1298,7 +1313,11 @@
 			net_os_send_hang_message(net);
 		}
 		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
 		return -ENODEV;
+#else
+		return NETDEV_TX_BUSY;
+#endif
 	}
 
 	ifidx = dhd_net2idx(dhd, net);
@@ -1306,7 +1325,11 @@
 		DHD_ERROR(("%s: bad ifidx %d\n", __FUNCTION__, ifidx));
 		netif_stop_queue(net);
 		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
 		return -ENODEV;
+#else
+		return NETDEV_TX_BUSY;
+#endif
 	}
 
 	/* Make sure there's enough room for any header */
@@ -1361,7 +1384,11 @@
 	DHD_OS_WAKE_UNLOCK(&dhd->pub);
 
 	/* Return ok: we always eat the packet */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
 	return 0;
+#else
+	return NETDEV_TX_OK;
+#endif
 }
 
 void
@@ -1819,7 +1846,8 @@
 	}
 #endif /* DHDTHREAD */
 
-	tasklet_schedule(&dhd->tasklet);
+	if (dhd->dhd_tasklet_create)
+		tasklet_schedule(&dhd->tasklet);
 }
 
 #ifdef TOE
@@ -2229,13 +2257,15 @@
 	}
 #endif /* WLMEDIA_HTSF */
 
-#ifdef BCM_FD_AGGR
 	if ((ioc.cmd == WLC_SET_VAR || ioc.cmd == WLC_GET_VAR) &&
 		ioc.buf != NULL && strncmp("rpc_", ioc.buf, 4) == 0) {
+#ifdef BCM_FD_AGGR
 		bcmerror = dhd_fdaggr_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen);
+#else
+		bcmerror = BCME_UNSUPPORTED;
+#endif
 		goto done;
 	}
-#endif
 	bcmerror = dhd_wl_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen);
 
 done:
@@ -2351,7 +2381,7 @@
 dhd_open(struct net_device *net)
 {
 	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
-
+	uint up = 0;
 #ifdef TOE
 	uint32 toe_ol;
 #endif
@@ -2438,6 +2468,10 @@
 	netif_start_queue(net);
 	dhd->pub.up = 1;
 
+	/* Fire a WLC_UP for primary interface to enable RF */
+	if (ifidx == 0)
+		dhd_wl_ioctl_cmd(&dhd->pub, WLC_UP, (char *)&up, sizeof(up), TRUE, 0);
+
 #ifdef BCMDBGFS
 	dhd_dbg_init(&dhd->pub);
 #endif
@@ -2448,6 +2482,32 @@
 	return ret;
 }
 
+int dhd_do_driver_init(struct net_device *net)
+{
+	dhd_info_t *dhd = NULL;
+
+	if (!net) {
+		DHD_ERROR(("Primary Interface not initialized \n"));
+		return -EINVAL;
+	}
+
+	dhd = *(dhd_info_t **)netdev_priv(net);
+
+	/* If driver is already initialized, do nothing
+	 */
+	if (dhd->pub.busstate == DHD_BUS_DATA) {
+		DHD_TRACE(("Driver already Inititalized. Nothing to do"));
+		return 0;
+	}
+
+	if (dhd_open(net) < 0) {
+		DHD_ERROR(("Driver Init Failed \n"));
+		return -1;
+	}
+
+	return 0;
+}
+
 osl_t *
 dhd_osl_attach(void *pdev, uint bustype)
 {
@@ -2463,7 +2523,9 @@
 	osl_detach(osh);
 #if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
 	up(&dhd_registration_sem);
+#if	defined(BCMLXSDMMC)
 	up(&dhd_chipup_sem);
+#endif
 #endif 
 }
 
@@ -2491,6 +2553,7 @@
 		}
 
 	memset(ifp, 0, sizeof(dhd_if_t));
+	ifp->event2cfg80211 = FALSE;
 	ifp->info = dhd;
 	dhd->iflist[ifidx] = ifp;
 	strncpy(ifp->name, name, IFNAMSIZ);
@@ -2507,6 +2570,10 @@
 	} else
 		ifp->net = (struct net_device *)handle;
 
+	if (ifidx == 0) {
+		ifp->event2cfg80211 = TRUE;
+	}
+
 	return 0;
 }
 
@@ -2538,7 +2605,7 @@
 	.ndo_do_ioctl = dhd_ioctl_entry,
 	.ndo_start_xmit = dhd_start_xmit,
 	.ndo_set_mac_address = dhd_set_mac_address,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
 	.ndo_set_rx_mode = dhd_set_multicast_list,
 #else
 	.ndo_set_multicast_list = dhd_set_multicast_list,
@@ -2550,7 +2617,7 @@
 	.ndo_do_ioctl = dhd_ioctl_entry,
 	.ndo_start_xmit = dhd_start_xmit,
 	.ndo_set_mac_address = dhd_set_mac_address,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
 	.ndo_set_rx_mode = dhd_set_multicast_list,
 #else
 	.ndo_set_multicast_list = dhd_set_multicast_list,
@@ -2590,9 +2657,8 @@
 #ifdef DHDTHREAD
 	dhd->thr_dpc_ctl.thr_pid = DHD_PID_KT_TL_INVALID;
 	dhd->thr_wdt_ctl.thr_pid = DHD_PID_KT_INVALID;
-#else
-	dhd->dhd_tasklet_create = FALSE;
 #endif /* DHDTHREAD */
+	dhd->dhd_tasklet_create = FALSE;
 	dhd->thr_sysioc_ctl.thr_pid = DHD_PID_KT_INVALID;
 	dhd_state |= DHD_ATTACH_STATE_DHD_ALLOC;
 
@@ -2892,6 +2958,36 @@
 	return 0;
 }
 
+#if !defined(AP) && defined(WLP2P)
+/* For Android ICS MR2 release, the concurrent mode is enabled by default and the firmware
+ * name would be fw_bcmdhd.bin. So we need to determine whether P2P is enabled in the STA
+ * firmware and accordingly enable concurrent mode (Apply P2P settings). SoftAP firmware
+ * would still be named as fw_bcmdhd_apsta.
+ */
+static u32
+dhd_concurrent_fw(dhd_pub_t *dhd)
+{
+	int ret = 0;
+	char buf[WLC_IOCTL_SMLEN];
+
+	if ((!op_mode) && (strstr(fw_path, "_p2p") == NULL) &&
+		(strstr(fw_path, "_apsta") == NULL)) {
+		/* Given path is for the STA firmware. Check whether P2P support is present in
+		 * the firmware. If so, set mode as P2P (concurrent support).
+		 */
+		memset(buf, 0, sizeof(buf));
+		bcm_mkiovar("p2p", 0, 0, buf, sizeof(buf));
+		if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf),
+			FALSE, 0)) < 0) {
+			DHD_TRACE(("%s: Get P2P failed (error=%d)\n", __FUNCTION__, ret));
+		} else if (buf[0] == 1) {
+			DHD_TRACE(("%s: P2P is supported\n", __FUNCTION__));
+			return 1;
+		}
+	}
+	return 0;
+}
+#endif 
 int
 dhd_preinit_ioctls(dhd_pub_t *dhd)
 {
@@ -2899,7 +2995,6 @@
 	char eventmask[WL_EVENTING_MASK_LEN];
 	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
 
-	uint up = 0;
 	uint power_mode = PM_FAST;
 	uint32 dongle_align = DHD_SDALIGN;
 	uint32 glom = 0;
@@ -2914,6 +3009,7 @@
 	char buf[WLC_IOCTL_SMLEN];
 	char *ptr;
 	uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
+	uint16 chipID;
 #if defined(SOFTAP)
 	uint dtim = 1;
 #endif
@@ -2958,7 +3054,7 @@
 #endif /* GET_CUSTOM_MAC_ENABLE */
 
 #ifdef SET_RANDOM_MAC_SOFTAP
-	if (strstr(fw_path, "_apsta") != NULL) {
+	if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == 0x02)) {
 		uint rand_mac;
 
 		srandom32((uint)jiffies);
@@ -2982,7 +3078,8 @@
 	DHD_TRACE(("Firmware = %s\n", fw_path));
 #if !defined(AP) && defined(WLP2P)
 	/* Check if firmware with WFD support used */
-	if (strstr(fw_path, "_p2p") != NULL) {
+	if ((!op_mode && strstr(fw_path, "_p2p") != NULL) || (op_mode == 0x04) ||
+		(dhd_concurrent_fw(dhd))) {
 		bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf));
 		if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
 			iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
@@ -2992,14 +3089,16 @@
 #if defined(ARP_OFFLOAD_SUPPORT)
 			arpoe = 0;
 #endif /* (ARP_OFFLOAD_SUPPORT) */
+#ifdef PKT_FILTER_SUPPORT
 			dhd_pkt_filter_enable = FALSE;
+#endif
 		}
 	}
 #endif 
 
 #if !defined(AP) && defined(WL_CFG80211)
 	/* Check if firmware with HostAPD support used */
-	if (strstr(fw_path, "_apsta") != NULL) {
+	if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == 0x02)) {
 			/* Turn off MPC in AP mode */
 			bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf));
 			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
@@ -3010,7 +3109,9 @@
 #if defined(ARP_OFFLOAD_SUPPORT)
 				arpoe = 0;
 #endif /* (ARP_OFFLOAD_SUPPORT) */
+#ifdef PKT_FILTER_SUPPORT
 				dhd_pkt_filter_enable = FALSE;
+#endif
 			}
 	}
 #endif 
@@ -3018,7 +3119,9 @@
 	if ((dhd->op_mode != WFD_MASK) && (dhd->op_mode != HOSTAPD_MASK)) {
 		/* STA only operation mode */
 		dhd->op_mode |= STA_MASK;
+#ifdef PKT_FILTER_SUPPORT
 		dhd_pkt_filter_enable = TRUE;
+#endif
 	}
 
 	DHD_ERROR(("Firmware up: op_mode=%d, "
@@ -3047,9 +3150,13 @@
 	bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf));
 	dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
 
-	/* disable glom option per default */
-	bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
-	dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+	/* disable glom option for some chips */
+	chipID = (uint16)dhd_bus_chip_id(dhd);
+	if  ((chipID == BCM4330_CHIP_ID) || (chipID == BCM4329_CHIP_ID)) {
+		DHD_INFO(("%s disable glom for chipID=0x%X\n", __FUNCTION__, chipID));
+		bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
+		dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+	}
 
 	/* Setup timeout if Beacons are lost and roam is off to report link down */
 	bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
@@ -3155,11 +3262,11 @@
 #else
 	if (arpoe) {
 #endif 
+		dhd_arp_offload_enable(dhd, TRUE);
 		dhd_arp_offload_set(dhd, dhd_arp_mode);
-		dhd_arp_offload_enable(dhd, arpoe);
 	} else {
-		dhd_arp_offload_set(dhd, 0);
 		dhd_arp_offload_enable(dhd, FALSE);
+		dhd_arp_offload_set(dhd, 0);
 	}
 #endif /* ARP_OFFLOAD_SUPPORT */
 
@@ -3182,12 +3289,6 @@
 #endif /* defined(SOFTAP) */
 #endif /* PKT_FILTER_SUPPORT */
 
-	/* Force STA UP */
-	if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&up, sizeof(up), TRUE, 0)) < 0) {
-		DHD_ERROR(("%s Setting WL UP failed %d\n", __FUNCTION__, ret));
-		goto done;
-	}
-
 	/* query for 'ver' to get version info from firmware */
 	memset(buf, 0, sizeof(buf));
 	ptr = buf;
@@ -3697,7 +3798,7 @@
 {
 	int error = 0;
 
-#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+#if 1 && defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
 	int retry = POWERUP_MAX_RETRY;
 	int chip_up = 0;
 #endif 
@@ -3722,15 +3823,15 @@
 	} while (0);
 #endif 
 
-#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+#if 1 && defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
 	do {
+		sema_init(&dhd_chipup_sem, 0);
+		dhd_bus_reg_sdio_notify(&dhd_chipup_sem);
 		dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
 #if defined(CONFIG_WIFI_CONTROL_FUNC)
 		if (wl_android_wifictrl_func_add() < 0)
 			goto fail_1;
 #endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
-		sema_init(&dhd_chipup_sem, 0);
-		dhd_bus_reg_sdio_notify(&dhd_chipup_sem);
 		if (down_timeout(&dhd_chipup_sem,
 			msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) {
 			dhd_bus_unreg_sdio_notify();
@@ -3750,6 +3851,13 @@
 		DHD_ERROR(("\nfailed to power up wifi chip, max retry reached, exits **\n\n"));
 		return -ENODEV;
 	}
+#else
+	dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+	if (wl_android_wifictrl_func_add() < 0)
+		goto fail_1;
+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
+
 #endif 
 
 #if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -3949,10 +4057,10 @@
 	 * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
 	 * ???
 	 */
-	if (IS_ERR(fp))
+	 if (IS_ERR(fp))
 		 fp = NULL;
 
-	return fp;
+	 return fp;
 }
 
 int
@@ -4107,7 +4215,13 @@
 #endif /* defined(CONFIG_WIRELESS_EXT)  */
 
 #ifdef WL_CFG80211
-
+	if ((ntoh32(event->event_type) == WLC_E_IF) &&
+		(((dhd_if_event_t *)*data)->action == WLC_E_IF_ADD))
+		/* If ADD_IF has been called directly by wl utility then we
+		 * should not report this. In case if ADD_IF was called from
+		 * CFG stack, then too this event need not be reported back
+		 */
+		return (BCME_OK);
 	if ((wl_cfg80211_is_progress_ifchange() ||
 		wl_cfg80211_is_progress_ifadd()) && (*ifidx != 0)) {
 		/*
@@ -4119,7 +4233,7 @@
 
 	ASSERT(dhd->iflist[*ifidx] != NULL);
 	ASSERT(dhd->iflist[*ifidx]->net != NULL);
-	if (dhd->iflist[*ifidx]->net) {
+	if (dhd->iflist[*ifidx]->event2cfg80211 && dhd->iflist[*ifidx]->net) {
 		wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, *data);
 	}
 #endif /* defined(WL_CFG80211) */
@@ -4224,7 +4338,7 @@
 		else {
 			/* Could not allocate a sk_buf */
 			DHD_ERROR(("%s: unable to alloc sk_buf", __FUNCTION__));
-}
+		}
 		break;
 	} /* case WLC_E_BTA_HCI_EVENT */
 #endif /* WLBTAMP */
@@ -4418,6 +4532,8 @@
 #endif
 #if defined(WL_CFG80211)
 			ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
+			dev_close(dev);
+			dev_open(dev);
 #endif
 		}
 	}
@@ -4722,8 +4838,7 @@
 extern int dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits);
 
 int dhd_wlfc_interface_event(struct dhd_info *dhd,
-       ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype,
-	uint8* ea)
+	ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea)
 {
 	if (dhd->pub.wlfc_state == NULL)
 		return BCME_OK;
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index 0b0377a..70e664e 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/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 309548 2012-01-20 01:13:08Z $
+ * $Id: dhd_sdio.c 325483 2012-04-03 13:22:22Z $
  */
 
 #include <typedefs.h>
@@ -162,7 +162,12 @@
 #define	REMAP_ENAB(bus)			((bus)->remap)
 #define	REMAP_ISADDR(bus, a)		(((a) >= ((bus)->orig_ramsize)) && ((a) < ((bus)->ramsize)))
 #define	KSO_ENAB(bus)			((bus)->kso)
-#define	SLPAUTO_ENAB(bus)		((bus)->_slpauto)
+#define	SR_ENAB(bus)			((bus)->_srenab)
+#define	SLPAUTO_ENAB(bus)		((SR_ENAB(bus)) && ((bus)->_slpauto))
+#define	MIN_RSRC_ADDR			(SI_ENUM_BASE + 0x618)
+#define	MIN_RSRC_SR			0x3
+#define	CORE_CAPEXT_ADDR		(SI_ENUM_BASE + 0x64c)
+#define	CORE_CAPEXT_SR_SUPPORTED_MASK	(1 << 1)
 
 #define	OOB_WAKEUP_ENAB(bus)		((bus)->_oobwakeup)
 #define	GPIO_DEV_SRSTATE		16	/* Host gpio17 mapped to device gpio0 SR state */
@@ -187,6 +192,7 @@
 	uint		ramrev;			/* SOCRAM core revision */
 	uint32		ramsize;		/* Size of RAM in SOCRAM (bytes) */
 	uint32		orig_ramsize;		/* Size of RAM in SOCRAM (bytes) */
+	uint32		srmemsize;		/* Size of SRMEM */
 
 	uint32		bus;			/* gSPI or SDIO bus */
 	uint32		hostintmask;		/* Copy of Host Interrupt Mask */
@@ -320,6 +326,7 @@
 	bool		kso;
 	bool		_slpauto;
 	bool		_oobwakeup;
+	bool		_srenab;
 } dhd_bus_t;
 
 /* clkstate */
@@ -582,6 +589,76 @@
 }
 #endif /* USE_OOB_GPIO1 */
 
+/*
+ * Query if FW is in SR mode
+ */
+static bool
+dhdsdio_sr_cap(dhd_bus_t *bus)
+{
+	bool cap = FALSE;
+	uint32 min = 0, core_capext;
+
+	core_capext = bcmsdh_reg_read(bus->sdh, CORE_CAPEXT_ADDR, 4);
+	if (!(core_capext & CORE_CAPEXT_SR_SUPPORTED_MASK) && !(bus->sih->chip == BCM4324_CHIP_ID))
+		return FALSE;
+
+	min = bcmsdh_reg_read(bus->sdh, MIN_RSRC_ADDR, 4);
+	if (min == MIN_RSRC_SR) {
+		cap = TRUE;
+
+		if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev < 3)) {
+			cap = FALSE;
+
+			DHD_ERROR(("Only 4334 >= B2 supports SR: curr rev %d\n",
+				bus->sih->chiprev));
+		}
+	}
+
+	return cap;
+}
+
+static int
+dhdsdio_srwar_init(dhd_bus_t *bus)
+{
+
+	bcmsdh_gpio_init(bus->sdh);
+
+#ifdef USE_OOB_GPIO1
+	dhdsdio_oobwakeup_init(bus);
+#endif
+
+
+	return 0;
+}
+
+static int
+dhdsdio_sr_init(dhd_bus_t *bus)
+{
+	uint8 val;
+	int err = 0;
+
+	if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev == 2))
+		dhdsdio_srwar_init(bus);
+
+	val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL, NULL);
+	val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
+	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL,
+		1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT, &err);
+	val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL, NULL);
+
+	/* Add CMD14 Support */
+	dhdsdio_devcap_set(bus,
+		(SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT));
+
+	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
+		SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_FORCE_HT, &err);
+
+	bus->_slpauto = dhd_slpauto ? TRUE : FALSE;
+
+	bus->_srenab = TRUE;
+
+	return 0;
+}
 
 /*
  * FIX: Be sure KSO bit is enabled
@@ -608,7 +685,6 @@
 			DHD_ERROR(("%s: SBSDIO_FUNC1_SLEEPCSR err: 0x%x\n", __FUNCTION__, err));
 	}
 
-
 	return 0;
 }
 
@@ -624,7 +700,7 @@
 
 	if (err)
 		DHD_TRACE(("%s: KSO toggle %d failed: %d\n", __FUNCTION__, on, err));
-	return 0;
+	return err;
 }
 
 static int
@@ -953,15 +1029,15 @@
 		}
 
 		bus->clkstate = CLK_SDONLY;
-
-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
-		DHD_INFO(("CLKCTL: turned OFF\n"));
-		if (err) {
-			DHD_ERROR(("%s: Failed access turning clock off: %d\n",
-			           __FUNCTION__, err));
-			return BCME_ERROR;
+		if (!SR_ENAB(bus)) {
+			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
+			DHD_INFO(("CLKCTL: turned OFF\n"));
+			if (err) {
+				DHD_ERROR(("%s: Failed access turning clock off: %d\n",
+				           __FUNCTION__, err));
+				return BCME_ERROR;
+			}
 		}
-
 	}
 	return BCME_OK;
 }
@@ -1108,6 +1184,7 @@
 #ifdef DHD_DEBUG
 		if (dhd_console_ms == 0)
 #endif /* DHD_DEBUG */
+		if (bus->poll == 0)
 			dhd_os_wd_timer(bus->dhd, 0);
 		break;
 	}
@@ -2176,24 +2253,36 @@
 dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh)
 {
 	uint32 addr;
-	int rv;
+	int rv, i;
+	uint32 shaddr = 0;
 
-	/* Read last word in memory to determine address of sdpcm_shared structure */
-	if ((rv = dhdsdio_membytes(bus, FALSE, bus->ramsize - 4, (uint8 *)&addr, 4)) < 0)
-		return rv;
+	shaddr = bus->ramsize - 4;
 
-	addr = ltoh32(addr);
+	i = 0;
+	do {
+		/* Read last word in memory to determine address of sdpcm_shared structure */
+		if ((rv = dhdsdio_membytes(bus, FALSE, shaddr, (uint8 *)&addr, 4)) < 0)
+			return rv;
 
-	DHD_INFO(("sdpcm_shared address 0x%08X\n", addr));
+		addr = ltoh32(addr);
 
-	/*
-	 * Check if addr is valid.
-	 * NVRAM length at the end of memory should have been overwritten.
-	 */
-	if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) {
-		DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", __FUNCTION__, addr));
-		return BCME_ERROR;
-	}
+		DHD_INFO(("sdpcm_shared address 0x%08X\n", addr));
+
+		/*
+		 * Check if addr is valid.
+		 * NVRAM length at the end of memory should have been overwritten.
+		 */
+		if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) {
+			if ((bus->srmemsize > 0) && (i++ == 0)) {
+				shaddr -= bus->srmemsize;
+			} else {
+				DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n",
+					__FUNCTION__, addr));
+				return BCME_ERROR;
+			}
+		} else
+			break;
+	} while (i < 2);
 
 	/* Read hndrte_shared structure */
 	if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)sh, sizeof(sdpcm_shared_t))) < 0)
@@ -3596,10 +3685,8 @@
 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL);
 	}
 
-	/* Restore previous clock setting */
-	if (SLPAUTO_ENAB(bus))
-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
-			SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_FORCE_HT, &err);
+	if (dhdsdio_sr_cap(bus))
+		dhdsdio_sr_init(bus);
 	else
 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
 			SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
@@ -5739,6 +5826,8 @@
 		return TRUE;
 	if (chipid == BCM4324_CHIP_ID)
 		return TRUE;
+	if (chipid == BCM4335_CHIP_ID)
+		return TRUE;
 	return FALSE;
 }
 
@@ -5748,13 +5837,9 @@
 {
 	int ret;
 	dhd_bus_t *bus;
-	dhd_cmn_t *cmn;
 #ifdef GET_CUSTOM_MAC_ENABLE
 	struct ether_addr ea_addr;
 #endif /* GET_CUSTOM_MAC_ENABLE */
-#ifdef PROP_TXSTATUS
-	uint up = 0;
-#endif
 
 	/* Init global variables at run-time, not as part of the declaration.
 	 * This is required to support init/de-init of the driver. Initialization
@@ -5850,15 +5935,11 @@
 	bus->usebufpool = FALSE; /* Use bufpool if allocated, else use locally malloced rxbuf */
 
 	/* attach the common module */
-	if (!(cmn = dhd_common_init(osh))) {
-		DHD_ERROR(("%s: dhd_common_init failed\n", __FUNCTION__));
-		goto fail;
-	}
+	dhd_common_init(osh);
 
 	/* attempt to attach to the dongle */
 	if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) {
 		DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __FUNCTION__));
-		dhd_common_deinit(NULL, cmn);
 		goto fail;
 	}
 
@@ -5868,9 +5949,6 @@
 		goto fail;
 	}
 
-	bus->dhd->cmn = cmn;
-	cmn->dhd = bus->dhd;
-
 	/* Allocate buffers */
 	if (!(dhdsdio_probe_malloc(bus, osh, sdh))) {
 		DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __FUNCTION__));
@@ -5920,10 +5998,6 @@
 		goto fail;
 	}
 
-#ifdef PROP_TXSTATUS
-	if (dhd_download_fw_on_driverload)
-		dhd_wl_ioctl_cmd(bus->dhd, WLC_UP, (char *)&up, sizeof(up), TRUE, 0);
-#endif
 	return bus;
 
 fail:
@@ -5939,6 +6013,7 @@
 	uint8 clkctl = 0;
 
 	bus->alp_only = TRUE;
+	bus->sih = NULL;
 
 	/* Return the window to backplane enumeration space for core access */
 	if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE)) {
@@ -6052,13 +6127,14 @@
 			goto fail;
 		}
 
-
 		bus->ramsize = bus->orig_ramsize;
 		if (dhd_dongle_memsize)
 			dhd_dongle_setmemsize(bus, dhd_dongle_memsize);
 
 		DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n",
 			bus->ramsize, bus->orig_ramsize));
+
+		bus->srmemsize = si_socram_srmem_size(bus->sih);
 	}
 
 	/* ...but normally deal with the SDPCMDEV core */
@@ -6231,22 +6307,12 @@
 
 	DHD_OS_WAKE_LOCK(bus->dhd);
 
-	if (!SLPAUTO_ENAB(bus)) {
-		/* Download the firmware */
-		dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
-	} else {
-		int err = 0;
-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
-			SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_ALP_AVAIL_REQ, &err);
-	}
+	/* Download the firmware */
+	dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
 
 	ret = _dhdsdio_download_firmware(bus) == 0;
 
-	/* For SLPAUTO, keep ALP_REQ otherwise device can go into deep-sleep
-	 * without host request
-	 */
-	if (!SLPAUTO_ENAB(bus))
-		dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
+	dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
 
 	DHD_OS_WAKE_UNLOCK(bus->dhd);
 	return ret;
@@ -6262,14 +6328,16 @@
 	if (bus) {
 		ASSERT(osh);
 
+		if (bus->dhd) {
+			dongle_isolation = bus->dhd->dongle_isolation;
+			dhd_detach(bus->dhd);
+		}
+
 		/* De-register interrupt handler */
 		bcmsdh_intr_disable(bus->sdh);
 		bcmsdh_intr_dereg(bus->sdh);
 
 		if (bus->dhd) {
-			dhd_common_deinit(bus->dhd, NULL);
-			dongle_isolation = bus->dhd->dongle_isolation;
-			dhd_detach(bus->dhd);
 			dhdsdio_release_dongle(bus, osh, dongle_isolation, TRUE);
 			dhd_free(bus->dhd);
 			bus->dhd = NULL;
@@ -6393,6 +6461,7 @@
 	bcmsdh_unregister();
 }
 
+#if defined(BCMLXSDMMC)
 /* Register a dummy SDIO client driver in order to be notified of new SDIO device */
 int dhd_bus_reg_sdio_notify(void* semaphore)
 {
@@ -6403,6 +6472,7 @@
 {
 	bcmsdh_unreg_sdio_notify();
 }
+#endif /* defined(BCMLXSDMMC) */
 
 #ifdef BCMEMBEDIMAGE
 static int
@@ -6852,6 +6922,13 @@
 	return bcmerror;
 }
 
+/* Get Chip ID version */
+uint dhd_bus_chip_id(dhd_pub_t *dhdp)
+{
+	dhd_bus_t *bus = dhdp->bus;
+
+	return  bus->sih->chip;
+}
 int
 dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size)
 {
diff --git a/drivers/net/wireless/bcmdhd/dhd_wlfc.h b/drivers/net/wireless/bcmdhd/dhd_wlfc.h
index 42c3a64..09a3d34 100644
--- a/drivers/net/wireless/bcmdhd/dhd_wlfc.h
+++ b/drivers/net/wireless/bcmdhd/dhd_wlfc.h
@@ -18,7 +18,7 @@
 *      Notwithstanding the above, under no circumstances may you combine this
 * 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_wlfc.h 294267 2011-11-04 23:41:52Z $
+* $Id: dhd_wlfc.h 322459 2012-03-20 22:36:07Z $
 *
 */
 #ifndef __wlfc_host_driver_definitions_h__
@@ -62,6 +62,7 @@
 typedef enum ewlfc_mac_entry_action {
 	eWLFC_MAC_ENTRY_ACTION_ADD,
 	eWLFC_MAC_ENTRY_ACTION_DEL,
+	eWLFC_MAC_ENTRY_ACTION_UPDATE,
 	eWLFC_MAC_ENTRY_ACTION_MAX
 } ewlfc_mac_entry_action_t;
 
@@ -222,7 +223,7 @@
 	athost_wl_stat_counters_t stats;
 
 	/* the additional ones are for bc/mc and ATIM FIFO */
-	int     FIFO_credit[AC_COUNT + 2];
+	int		FIFO_credit[AC_COUNT + 2];
 
 	/* Credit borrow counts for each FIFO from each of the other FIFOs */
 	int		credits_borrowed[AC_COUNT + 2][AC_COUNT + 2];
diff --git a/drivers/net/wireless/bcmdhd/hndpmu.c b/drivers/net/wireless/bcmdhd/hndpmu.c
index d5c757d5..eeee5ea 100644
--- a/drivers/net/wireless/bcmdhd/hndpmu.c
+++ b/drivers/net/wireless/bcmdhd/hndpmu.c
@@ -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: hndpmu.c 309997 2012-01-21 06:26:00Z $
+ * $Id: hndpmu.c 324060 2012-03-27 23:26:47Z $
  */
 
 #include <bcm_cfg.h>
diff --git a/drivers/net/wireless/bcmdhd/include/bcmcdc.h b/drivers/net/wireless/bcmdhd/include/bcmcdc.h
index a21eae3..9bae1c2 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmcdc.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmcdc.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: bcmcdc.h 309825 2012-01-20 20:16:13Z $
+ * $Id: bcmcdc.h 318308 2012-03-02 02:23:42Z $
  */
 #ifndef _bcmcdc_h_
 #define	_bcmcdc_h_
@@ -83,6 +83,7 @@
 #define BDC_FLAG_80211_PKT	0x01	
 #define BDC_FLAG_SUM_GOOD	0x04	
 #define BDC_FLAG_SUM_NEEDED	0x08	
+#define BDC_FLAG_EVENT_MSG	0x08	
 #define BDC_FLAG_VER_MASK	0xf0	
 #define BDC_FLAG_VER_SHIFT	4	
 
diff --git a/drivers/net/wireless/bcmdhd/include/bcmdefs.h b/drivers/net/wireless/bcmdhd/include/bcmdefs.h
index c7f4cf4..a35ed72 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmdefs.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmdefs.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: bcmdefs.h 309174 2012-01-18 23:10:14Z $
+ * $Id: bcmdefs.h 316830 2012-02-23 20:29:22Z $
  */
 
 #ifndef	_bcmdefs_h_
@@ -55,6 +55,7 @@
 #define CONST	const
 #ifndef BCMFASTPATH
 #define BCMFASTPATH
+#define BCMFASTPATH_HOST
 #endif 
 
 
@@ -193,6 +194,11 @@
 #define BCMDONGLEOVERHEAD	(BCMDONGLEHDRSZ + BCMDONGLEPADSZ)
 
 
+#if defined(NO_BCMDBG_ASSERT)
+# undef BCMDBG_ASSERT
+# undef BCMASSERT_LOG
+#endif
+
 #if defined(BCMASSERT_LOG)
 #define BCMASSERT_SUPPORT
 #endif 
diff --git a/drivers/net/wireless/bcmdhd/include/bcmdevs.h b/drivers/net/wireless/bcmdhd/include/bcmdevs.h
index c49d68e..da0e92f 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmdevs.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmdevs.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: bcmdevs.h 309997 2012-01-21 06:26:00Z $
+ * $Id: bcmdevs.h 324551 2012-03-29 18:36:03Z $
  */
 
 #ifndef	_BCMDEVS_H
@@ -159,9 +159,12 @@
 #define BCM94313HMG_SSID_VEN1	0x0609
 
 
-#define BCM4335_D11AC_ID	0x43a9
-#define BCM4335_D11AC2G_ID	0x43aa
-#define BCM4335_D11AC5G_ID	0x43ab
+#define BCM4335_D11AC_ID	0x43ae
+#define BCM4335_D11AC2G_ID	0x43af
+#define BCM4335_D11AC5G_ID	0x43b0
+#define BCM4352_D11AC_ID	0x43b1		
+#define BCM4352_D11AC2G_ID	0x43b2		
+#define BCM4352_D11AC5G_ID	0x43b3		
 
 #define	BCMGPRS_UART_ID		0x4333		
 #define	BCMGPRS2_UART_ID	0x4344		
@@ -258,6 +261,8 @@
 #define	BCM43242_CHIP_ID	43242		
 #define BCM4334_CHIP_ID		0x4334		
 #define BCM4360_CHIP_ID		0x4360          
+#define BCM4352_CHIP_ID		0x4352          
+#define BCM43526_CHIP_ID	0xAA06
 
 #define BCM4335_CHIP_ID         0x4335
 
diff --git a/drivers/net/wireless/bcmdhd/include/bcmnvram.h b/drivers/net/wireless/bcmdhd/include/bcmnvram.h
index ba6726b..ce0e035 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmnvram.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmnvram.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: bcmnvram.h 288000 2011-10-05 19:05:16Z $
+ * $Id: bcmnvram.h 320632 2012-03-12 19:22:42Z $
  */
 
 #ifndef _bcmnvram_h_
@@ -133,4 +133,47 @@
 
 #define BCM_JUMBO_NVRAM_DELIMIT '\n'
 #define BCM_JUMBO_START "Broadcom Jumbo Nvram file"
+
+#if (defined(FAILSAFE_UPGRADE) || defined(CONFIG_FAILSAFE_UPGRADE) || \
+	defined(__CONFIG_FAILSAFE_UPGRADE_SUPPORT__))
+#define IMAGE_SIZE "image_size"
+#define BOOTPARTITION "bootpartition"
+#define IMAGE_BOOT BOOTPARTITION
+#define PARTIALBOOTS "partialboots"
+#define MAXPARTIALBOOTS "maxpartialboots"
+#define IMAGE_1ST_FLASH_TRX "flash0.trx"
+#define IMAGE_1ST_FLASH_OS "flash0.os"
+#define IMAGE_2ND_FLASH_TRX "flash0.trx2"
+#define IMAGE_2ND_FLASH_OS "flash0.os2"
+#define IMAGE_FIRST_OFFSET "image_first_offset"
+#define IMAGE_SECOND_OFFSET "image_second_offset"
+#define LINUX_FIRST "linux"
+#define LINUX_SECOND "linux2"
+#endif
+
+#if (defined(DUAL_IMAGE) || defined(CONFIG_DUAL_IMAGE) || \
+	defined(__CONFIG_DUAL_IMAGE_FLASH_SUPPORT__))
+
+#define IMAGE_BOOT "image_boot"
+#define BOOTPARTITION IMAGE_BOOT
+
+#define IMAGE_1ST_FLASH_TRX "flash0.trx"
+#define IMAGE_1ST_FLASH_OS "flash0.os"
+#define IMAGE_2ND_FLASH_TRX "flash0.trx2"
+#define IMAGE_2ND_FLASH_OS "flash0.os2"
+#define IMAGE_SIZE "image_size"
+
+
+#define IMAGE_FIRST_OFFSET "image_first_offset"
+#define IMAGE_SECOND_OFFSET "image_second_offset"
+
+
+#define LINUX_FIRST "linux"
+#define LINUX_SECOND "linux2"
+#define POLICY_TOGGLE "toggle"
+#define LINUX_PART_TO_FLASH "linux_to_flash"
+#define LINUX_FLASH_POLICY "linux_flash_policy"
+
+#endif 
+
 #endif 
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
index b6fdd1f..36c3604 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
@@ -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: bcmsdbus.h 299859 2011-12-01 03:53:27Z $
+ * $Id: bcmsdbus.h 320190 2012-03-09 19:13:53Z $
  */
 
 #ifndef	_sdio_api_h_
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh.h b/drivers/net/wireless/bcmdhd/include/bcmsdh.h
index 177498a..acab225 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdh.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdh.h
@@ -23,7 +23,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.h 309548 2012-01-20 01:13:08Z $
+ * $Id: bcmsdh.h 313885 2012-02-09 03:55:26Z $
  */
 
 /**
@@ -55,7 +55,13 @@
  *    implementation may maintain a single "default" handle (e.g. the first or
  *    most recent one) to enable single-instance implementations to pass NULL.
  */
+
+#if defined(NDIS630)
+extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl,
+	void **regsva, uint irq, shared_info_t *sh);
+#else
 extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq);
+#endif
 
 /* Detach - freeup resources allocated in attach */
 extern int bcmsdh_detach(osl_t *osh, void *sdh);
@@ -70,6 +76,8 @@
 /* Register/deregister device interrupt handler. */
 extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
 extern int bcmsdh_intr_dereg(void *sdh);
+/* Enable/disable SD card interrupt forward */
+extern void bcmsdh_intr_forward(void *sdh, bool pass);
 
 #if defined(DHD_DEBUG)
 /* Query pending interrupt status from the host controller */
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h
index 6911420..80f3900 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.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: bcmsdh_sdmmc.h 294363 2011-11-06 23:02:20Z $
+ * $Id: bcmsdh_sdmmc.h 313732 2012-02-08 19:49:00Z $
  */
 
 #ifndef __BCMSDH_SDMMC_H__
@@ -82,9 +82,10 @@
 	uint8 		num_funcs;		/* Supported funcs on client */
 	uint32 		com_cis_ptr;
 	uint32 		func_cis_ptr[SDIOD_MAX_IOFUNCS];
-	uint		max_dma_len;
-	uint		max_dma_descriptors;	/* DMA Descriptors supported by this controller. */
-//	SDDMA_DESCRIPTOR	SGList[32];	/* Scatter/Gather DMA List */
+
+#define SDIOH_SDMMC_MAX_SG_ENTRIES	32
+	struct scatterlist sg_list[SDIOH_SDMMC_MAX_SG_ENTRIES];
+	bool		use_rxchain;
 };
 
 /************************************************************
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h b/drivers/net/wireless/bcmdhd/include/bcmsdstd.h
index 16f084e..8acc004 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsdstd.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: bcmsdstd.h 294369 2011-11-06 23:22:23Z $
+ * $Id: bcmsdstd.h 324797 2012-03-30 11:02:00Z $
  */
 #ifndef	_BCM_SD_STD_H
 #define	_BCM_SD_STD_H
@@ -130,7 +130,7 @@
 	int8		sd_dma_mode;		/* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */
 	uint8 		num_funcs;		/* Supported funcs on client */
 	uint32 		com_cis_ptr;
-	uint32 		func_cis_ptr[SDIOD_MAX_FUNCS];
+	uint32 		func_cis_ptr[SDIOD_MAX_IOFUNCS];
 	void		*dma_buf;		/* DMA Buffer virtual address */
 	ulong		dma_phys;		/* DMA Buffer physical address */
 	void		*adma2_dscr_buf;	/* ADMA2 Descriptor Buffer virtual address */
@@ -157,8 +157,8 @@
 					 * HOST_SDR_12_25: SDR12 and SDR25 supported
 					 * HOST_SDR_50_104_DDR: one of SDR50/SDR104 or DDR50 supptd
 					 */
-	int	sd3_dat_state; 		/* data transfer state used for retuning check */
-	int	sd3_tun_state; 		/* tuning state used for retuning check */
+	volatile int	sd3_dat_state; 		/* data transfer state used for retuning check */
+	volatile int	sd3_tun_state; 		/* tuning state used for retuning check */
 	bool	sd3_tuning_reqd; 	/* tuning requirement parameter */
 	uint32	caps3;			/* cached value of 32 MSbits capabilities reg (SDIO 3.0) */
 };
@@ -181,6 +181,9 @@
 #define DATA_TRANSFER_IDLE 		0
 #define DATA_TRANSFER_ONGOING	1
 
+#define CHECK_TUNING_PRE_DATA	1
+#define CHECK_TUNING_POST_DATA	2
+
 /************************************************************
  * Internal interfaces: per-port references into bcmsdstd.c
  */
@@ -227,10 +230,12 @@
 extern void sdstd_3_enable_retuning_int(sdioh_info_t *sd);
 extern void sdstd_3_disable_retuning_int(sdioh_info_t *sd);
 extern bool sdstd_3_is_retuning_int_set(sdioh_info_t *sd);
+extern void sdstd_3_check_and_do_tuning(sdioh_info_t *sd, int tuning_param);
 extern bool sdstd_3_check_and_set_retuning(sdioh_info_t *sd);
 extern int sdstd_3_get_tune_state(sdioh_info_t *sd);
 extern int sdstd_3_get_data_state(sdioh_info_t *sd);
 extern void sdstd_3_set_tune_state(sdioh_info_t *sd, int state);
+extern void sdstd_3_set_data_state(sdioh_info_t *sd, int state);
 extern uint8 sdstd_3_get_tuning_exp(sdioh_info_t *sd);
 extern uint32 sdstd_3_get_uhsi_clkmode(sdioh_info_t *sd);
 extern int sdstd_3_clk_tuning(sdioh_info_t *sd, uint32 sd3ClkMode);
diff --git a/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h b/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h
index 98ddb00..9ed3a5d 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.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: bcmsrom_tbl.h 309193 2012-01-19 00:03:57Z $
+ * $Id: bcmsrom_tbl.h 322893 2012-03-22 03:31:32Z $
  */
 
 #ifndef	_bcmsrom_tbl_h_
@@ -732,6 +732,7 @@
 
 typedef struct {
 	uint8	tag;		/* Broadcom subtag name */
+	uint32	revmask;	/* Supported cis_sromrev */
 	uint8	len;		/* Length field of the tuple, note that it includes the
 				 * subtag name (1 byte): 1 + tuple content length
 				 */
@@ -744,94 +745,116 @@
 #define OTP_RAW1	(0xff - 4)	/* Like RAW, but comes first */
 
 static const cis_tuple_t cis_hnbuvars[] = {
-	{OTP_RAW1,		0, ""},	/* special case */
-	{OTP_VERS_1,		0, "smanf sproductname"},	/* special case (non BRCM tuple) */
-	{OTP_MANFID,		4, "2manfid 2prodid"},		/* special case (non BRCM tuple) */
+	{OTP_RAW1,		0xffffffff, 0, ""},	/* special case */
+	{OTP_VERS_1,	0xffffffff, 0, "smanf sproductname"},	/* special case (non BRCM tuple) */
+	{OTP_MANFID,	0xffffffff, 4, "2manfid 2prodid"},	/* special case (non BRCM tuple) */
 	/* Unified OTP: tupple to embed USB manfid inside SDIO CIS */
-	{HNBU_UMANFID,		8, "8usbmanfid"},
-	{HNBU_SROMREV,		2, "1sromrev"},
+	{HNBU_UMANFID,		0xffffffff, 8, "8usbmanfid"},
+	{HNBU_SROMREV,		0xffffffff, 2, "1sromrev"},
 	/* NOTE: subdevid is also written to boardtype.
 	 *       Need to write HNBU_BOARDTYPE to change it if it is different.
 	 */
-	{HNBU_CHIPID,		11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"},
-	{HNBU_BOARDREV,		3, "2boardrev"},
-	{HNBU_PAPARMS,		10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"},
-	{HNBU_AA,		3, "1aa2g 1aa5g"},
-	{HNBU_AA,		3, "1aa0 1aa1"}, /* backward compatibility */
-	{HNBU_AG,		5, "1ag0 1ag1 1ag2 1ag3"},
-	{HNBU_BOARDFLAGS,	9, "4boardflags 4boardflags2"},
-	{HNBU_LEDS,		5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"},
-	{HNBU_CCODE,		4, "2ccode 1cctl"},
-	{HNBU_CCKPO,		3, "2cckpo"},
-	{HNBU_OFDMPO,		5, "4ofdmpo"},
-	{HNBU_PAPARMS5G,	23, "2pa1b0 2pa1b1 2pa1b2 2pa1lob0 2pa1lob1 2pa1lob2 "
+	{HNBU_CHIPID,		0xffffffff, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"},
+	{HNBU_BOARDREV,		0xffffffff, 3, "2boardrev"},
+	{HNBU_PAPARMS,		0xffffffff, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"},
+	{HNBU_AA,		0xffffffff, 3, "1aa2g 1aa5g"},
+	{HNBU_AA,		0xffffffff, 3, "1aa0 1aa1"}, /* backward compatibility */
+	{HNBU_AG,		0xffffffff, 5, "1ag0 1ag1 1ag2 1ag3"},
+	{HNBU_BOARDFLAGS,	0xffffffff, 13, "4boardflags 4boardflags2 4boardflags3"},
+	{HNBU_LEDS,		0xffffffff, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"},
+	{HNBU_CCODE,		0xffffffff, 4, "2ccode 1cctl"},
+	{HNBU_CCKPO,		0xffffffff, 3, "2cckpo"},
+	{HNBU_OFDMPO,		0xffffffff, 5, "4ofdmpo"},
+	{HNBU_PAPARMS5G,	0xffffffff, 23, "2pa1b0 2pa1b1 2pa1b2 2pa1lob0 2pa1lob1 2pa1lob2 "
 	"2pa1hib0 2pa1hib1 2pa1hib2 1pa1itssit "
 	"1pa1maxpwr 1pa1lomaxpwr 1pa1himaxpwr"},
-	{HNBU_RDLID,		3, "2rdlid"},
-	{HNBU_RSSISMBXA2G,	3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"}, /* special case */
-	{HNBU_RSSISMBXA5G,	3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"}, /* special case */
-	{HNBU_XTALFREQ,		5, "4xtalfreq"},
-	{HNBU_TRI2G,		2, "1tri2g"},
-	{HNBU_TRI5G,		4, "1tri5gl 1tri5g 1tri5gh"},
-	{HNBU_RXPO2G,		2, "1rxpo2g"},
-	{HNBU_RXPO5G,		2, "1rxpo5g"},
-	{HNBU_BOARDNUM,		3, "2boardnum"},
-	{HNBU_MACADDR,		7, "6macaddr"},	/* special case */
-	{HNBU_RDLSN,		3, "2rdlsn"},
-	{HNBU_BOARDTYPE,	3, "2boardtype"},
-	{HNBU_LEDDC,		3, "2leddc"},
-	{HNBU_RDLRNDIS,		2, "1rdlndis"},
-	{HNBU_CHAINSWITCH,	5, "1txchain 1rxchain 2antswitch"},
-	{HNBU_REGREV,		2, "1regrev"},
-	{HNBU_FEM,		5, "0antswctl2g 0triso2g 0pdetrange2g 0extpagain2g 0tssipos2g "
-				   "0antswctl5g 0triso5g 0pdetrange5g 0extpagain5g 0tssipos5g"
-				   }, /* special case */
-	{HNBU_PAPARMS_C0,	31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 "
-	"2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 "
-	"2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 "
-	"2pa5ghw1a0 2pa5ghw2a0"},
-	{HNBU_PAPARMS_C1,	31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 "
-	"2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 "
-	"2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 "
-	"2pa5ghw1a1 2pa5ghw2a1"},
-	{HNBU_PO_CCKOFDM,	19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo "
+	{HNBU_RDLID,		0xffffffff, 3, "2rdlid"},
+	{HNBU_RSSISMBXA2G, 0xffffffff, 3, "0rssismf2g 0rssismc2g "
+	"0rssisav2g 0bxa2g"}, /* special case */
+	{HNBU_RSSISMBXA5G, 0xffffffff, 3, "0rssismf5g 0rssismc5g "
+	"0rssisav5g 0bxa5g"}, /* special case */
+	{HNBU_XTALFREQ,		0xffffffff, 5, "4xtalfreq"},
+	{HNBU_TRI2G,		0xffffffff, 2, "1tri2g"},
+	{HNBU_TRI5G,		0xffffffff, 4, "1tri5gl 1tri5g 1tri5gh"},
+	{HNBU_RXPO2G,		0xffffffff, 2, "1rxpo2g"},
+	{HNBU_RXPO5G,		0xffffffff, 2, "1rxpo5g"},
+	{HNBU_BOARDNUM,		0xffffffff, 3, "2boardnum"},
+	{HNBU_MACADDR,		0xffffffff, 7, "6macaddr"},	/* special case */
+	{HNBU_RDLSN,		0xffffffff, 3, "2rdlsn"},
+	{HNBU_BOARDTYPE,	0xffffffff, 3, "2boardtype"},
+	{HNBU_LEDDC,		0xffffffff, 3, "2leddc"},
+	{HNBU_RDLRNDIS,		0xffffffff, 2, "1rdlndis"},
+	{HNBU_CHAINSWITCH,	0xffffffff, 5, "1txchain 1rxchain 2antswitch"},
+	{HNBU_REGREV,		0xffffffff, 2, "1regrev"},
+	{HNBU_FEM,		0x000007fe, 5, "0antswctl2g 0triso2g 0pdetrange2g 0extpagain2g "
+	"0tssipos2g 0antswctl5g 0triso5g 0pdetrange5g 0extpagain5g 0tssipos5g"}, /* special case */
+	{HNBU_PAPARMS_C0,	0x000007fe, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 "
+	"2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 2pa5gw1a0 2pa5gw2a0 "
+	"2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 2pa5ghw1a0 2pa5ghw2a0"},
+	{HNBU_PAPARMS_C1,	0x000007fe, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 "
+	"2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 2pa5gw1a1 2pa5gw2a1 "
+	"2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 2pa5ghw1a1 2pa5ghw2a1"},
+	{HNBU_PO_CCKOFDM,	0xffffffff, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo "
 	"4ofdm5ghpo"},
-	{HNBU_PO_MCS2G,		17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 "
+	{HNBU_PO_MCS2G,		0xffffffff, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 "
 	"2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"},
-	{HNBU_PO_MCS5GM,	17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 "
+	{HNBU_PO_MCS5GM,	0xffffffff, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 "
 	"2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"},
-	{HNBU_PO_MCS5GLH,	33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 "
+	{HNBU_PO_MCS5GLH,	0xffffffff, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 "
 	"2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 "
 	"2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 "
 	"2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"},
-	{HNBU_CCKFILTTYPE,	2, "1cckdigfilttype"},
-	{HNBU_PO_CDD,		3, "2cddpo"},
-	{HNBU_PO_STBC,		3, "2stbcpo"},
-	{HNBU_PO_40M,		3, "2bw40po"},
-	{HNBU_PO_40MDUP,	3, "2bwduppo"},
-	{HNBU_RDLRWU,		2, "1rdlrwu"},
-	{HNBU_WPS,		3, "1wpsgpio 1wpsled"},
-	{HNBU_USBFS,		2, "1usbfs"},
-	{HNBU_ELNA2G,           2, "1elna2g"},
-	{HNBU_ELNA5G,           2, "1elna5g"},
-	{HNBU_CUSTOM1,		5, "4customvar1"},
-	{OTP_RAW,		0, ""},	/* special case */
-	{HNBU_OFDMPO5G,		13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"},
-	{HNBU_USBEPNUM,		3, "2usbepnum"},
-	{HNBU_CCKBW202GPO,	5, "2cckbw202gpo 2cckbw20ul2gpo"},
-	{HNBU_LEGOFDMBW202GPO,	9, "4legofdmbw202gpo 4legofdmbw20ul2gp"},
-	{HNBU_LEGOFDMBW205GPO,	25, "4legofdmbw205glpo 4legofdmbw20ul5glpo 4legofdmbw205gmpo "
-	"4legofdmbw20ul5gmpo 4legofdmbw205ghpo 4legofdmbw20ul5ghpo"},
-	{HNBU_MCS2GPO,	13,	"4mcsbw202gpo 4mcsbw20ul2gpo 4mcsbw402gpo"},
-	{HNBU_MCS5GLPO,	13,	"4mcsbw205glpo 4mcsbw20ul5glpo 4mcsbw405glpo"},
-	{HNBU_MCS5GMPO,	13,	"4mcsbw205gmpo 4mcsbw20ul5gmpo 4mcsbw405gmpo"},
-	{HNBU_MCS5GHPO,	13,	"4mcsbw205ghpo 4mcsbw20ul5ghpo 4mcsbw405ghpo"},
-	{HNBU_MCS32PO,	3,	"2mcs32po"},
-	{HNBU_LEG40DUPPO, 	3,	"2legofdm40duppo"},
-	{HNBU_TEMPTHRESH, 	3,	"1tempthresh 1periodhyst"},
-	{HNBU_UUID, 	17,	"16uuid"},
-	{HNBU_WOWLGPIO,     2,  "1wowl_gpio"},
-	{0xFF,			0, ""}
+	{HNBU_CCKFILTTYPE,	0xffffffff, 2, "1cckdigfilttype"},
+	{HNBU_PO_CDD,		0xffffffff, 3, "2cddpo"},
+	{HNBU_PO_STBC,		0xffffffff, 3, "2stbcpo"},
+	{HNBU_PO_40M,		0xffffffff, 3, "2bw40po"},
+	{HNBU_PO_40MDUP,	0xffffffff, 3, "2bwduppo"},
+	{HNBU_RDLRWU,		0xffffffff, 2, "1rdlrwu"},
+	{HNBU_WPS,		0xffffffff, 3, "1wpsgpio 1wpsled"},
+	{HNBU_USBFS,		0xffffffff, 2, "1usbfs"},
+	{HNBU_ELNA2G,           0xffffffff, 2, "1elna2g"},
+	{HNBU_ELNA5G,           0xffffffff, 2, "1elna5g"},
+	{HNBU_CUSTOM1,		0xffffffff, 5, "4customvar1"},
+	{OTP_RAW,		0xffffffff, 0, ""},	/* special case */
+	{HNBU_OFDMPO5G,		0xffffffff, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"},
+	{HNBU_USBEPNUM,		0xffffffff, 3, "2usbepnum"},
+	{HNBU_CCKBW202GPO,	0xffffffff, 5, "2cckbw202gpo 2cckbw20ul2gpo"},
+	{HNBU_LEGOFDMBW202GPO,	0xffffffff, 9, "4legofdmbw202gpo 4legofdmbw20ul2gp"},
+	{HNBU_LEGOFDMBW205GPO,	0xffffffff, 25, "4legofdmbw205glpo 4legofdmbw20ul5glpo "
+	"4legofdmbw205gmpo 4legofdmbw20ul5gmpo 4legofdmbw205ghpo 4legofdmbw20ul5ghpo"},
+	{HNBU_MCS2GPO,	0xffffffff, 13,	"4mcsbw202gpo 4mcsbw20ul2gpo 4mcsbw402gpo"},
+	{HNBU_MCS5GLPO,	0xffffffff, 13,	"4mcsbw205glpo 4mcsbw20ul5glpo 4mcsbw405glpo"},
+	{HNBU_MCS5GMPO,	0xffffffff, 13,	"4mcsbw205gmpo 4mcsbw20ul5gmpo 4mcsbw405gmpo"},
+	{HNBU_MCS5GHPO,	0xffffffff, 13,	"4mcsbw205ghpo 4mcsbw20ul5ghpo 4mcsbw405ghpo"},
+	{HNBU_MCS32PO,	0xffffffff, 3,	"2mcs32po"},
+	{HNBU_LEG40DUPPO, 	0xffffffff, 3,	"2legofdm40duppo"},
+	{HNBU_TEMPTHRESH, 	0xffffffff, 6,	"1tempthresh 1periodhyst 1tempoffset 1tempcoropt "
+	"1phycal_tempdelta"},
+	{HNBU_FEM_CFG,		0xfffff800, 5,	"2fem_cfg1 2fem_cfg2"},
+	{HNBU_ACPA_C0,		0xfffff800, 41,	"2subband5gver 2maxp2ga0 2*3pa2ga0 2rxgainsa0 "
+	"1*4maxp5ga0 2*12pa5ga0"},
+	{HNBU_ACPA_C1,		0xfffff800, 39,	"2maxp2ga1 2*3pa2ga1 2rxgainsa1 1*4maxp5ga1 "
+	"2*12pa5ga1"},
+	{HNBU_ACPA_C2,		0xfffff800, 39,	"2maxp2ga2 2*3pa2ga2 2rxgainsa2 1*4maxp5ga2 "
+	"2*12pa5ga2"},
+	{HNBU_MEAS_PWR,		0xfffff800, 5,	"1measpower 1measpower1 1measpower2 2rawtempsense"},
+	{HNBU_PDOFF,		0xfffff800, 13,	"2pdoffset40ma0 2pdoffset40ma1 2pdoffset40ma2 "
+	"2pdoffset80ma0 2pdoffset80ma1 2pdoffset80ma2"},
+	{HNBU_ACPPR_2GPO,	0xfffff800, 5,	"2dot11agofdmhrbw202gpo 2ofdmlrbw202gpo"},
+	{HNBU_ACPPR_5GPO,	0xfffff800, 31,	"4mcsbw805glpo 4mcsbw1605glpo 4mcsbw805gmpo "
+	"4mcsbw1605gmpo 4mcsbw805ghpo 4mcsbw1605ghpo 2mcslr5rlpo 2mcslr5gmpo 2mcslr5ghpo"},
+	{HNBU_ACPPR_SBPO,	0xfffff800, 33,	"2sb20in40hrrpo 2sb20in80and160hr5glpo "
+	"2sb40and80hr5glpo 2sb20in80and160hr5gmpo 2sb40and80hr5gmpo 2sb20in80and160hr5ghpo "
+	"2sb40and80hr5ghpo 2sb20in40lrpo 2sb20in80and160lr5glpo 2sb40and80lr5glpo "
+	"2sb20in80and160lr5gmpo 2sb40and80lr5gmpo 2sb20in80and160lr5ghpo 2sb40and80lr5ghpo "
+	"2dot11agduphrpo 2dot11agduplrpo"},
+	{HNBU_NOISELVL,		0xfffff800, 11, "2noiselvl2g 2noiselvl5gl 2noiselvl5gm "
+	"2noiselvl5gh 2noiselvl5gu"},
+	{HNBU_RXGAIN_ERR,	0xfffff800, 11, "2rxgainerr2g 2*4rxgainerr5g"},
+	{HNBU_AGBGA,		0xfffff800, 7, "1agbg0 1agbg1 1agbg2 1aga0 1aga1 1aga2"},
+	{HNBU_UUID, 		0xffffffff, 17,	"16uuid"},
+	{HNBU_WOWLGPIO,		0xffffffff, 2,  "1wowl_gpio"},
+	{0xFF,			0xffffffff, 0, ""}
 };
 
 #endif /* _bcmsrom_tbl_h_ */
diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h
index be3eba6..0225124 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmutils.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmutils.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: bcmutils.h 309397 2012-01-19 15:36:59Z $
+ * $Id: bcmutils.h 315959 2012-02-20 18:04:48Z $
  */
 
 #ifndef	_bcmutils_h_
@@ -643,6 +643,22 @@
 #define CRC32_GOOD_VALUE 0xdebb20e3	
 
 
+#define MACF				"%02x:%02x:%02x:%02x:%02x:%02x"
+#define ETHERP_TO_MACF(ea)	((struct ether_addr *) (ea))->octet[0], \
+							((struct ether_addr *) (ea))->octet[1], \
+							((struct ether_addr *) (ea))->octet[2], \
+							((struct ether_addr *) (ea))->octet[3], \
+							((struct ether_addr *) (ea))->octet[4], \
+							((struct ether_addr *) (ea))->octet[5]
+
+#define ETHER_TO_MACF(ea) 	(ea).octet[0], \
+							(ea).octet[1], \
+							(ea).octet[2], \
+							(ea).octet[3], \
+							(ea).octet[4], \
+							(ea).octet[5]
+
+
 typedef struct bcm_bit_desc {
 	uint32	bit;
 	const char* name;
diff --git a/drivers/net/wireless/bcmdhd/include/dbus.h b/drivers/net/wireless/bcmdhd/include/dbus.h
index 8c5a8cf..c5ea223 100644
--- a/drivers/net/wireless/bcmdhd/include/dbus.h
+++ b/drivers/net/wireless/bcmdhd/include/dbus.h
@@ -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: dbus.h 309193 2012-01-19 00:03:57Z $
+ * $Id: dbus.h 323680 2012-03-26 17:52:31Z $
  */
 
 #ifndef __DBUS_H__
@@ -68,8 +68,11 @@
 #define ERR_CBMASK_RXFAIL		0x00000002
 #define ERR_CBMASK_ALL			0xFFFFFFFF
 
-#define DBUS_CBCTL_WRITE		0
-#define DBUS_CBCTL_READ			1
+#define DBUS_CBCTL_WRITE			0
+#define DBUS_CBCTL_READ				1
+#if defined(INTR_EP_ENABLE)
+#define DBUS_CBINTR_POLL			2
+#endif /* defined(INTR_EP_ENABLE) */
 
 #define DBUS_TX_RETRY_LIMIT		3		/* retries for failed txirb */
 #define DBUS_TX_TIMEOUT_INTERVAL	250		/* timeout for txirb complete, in ms */
diff --git a/drivers/net/wireless/bcmdhd/include/dhdioctl.h b/drivers/net/wireless/bcmdhd/include/dhdioctl.h
index 69f56c5..0dd96ff 100644
--- a/drivers/net/wireless/bcmdhd/include/dhdioctl.h
+++ b/drivers/net/wireless/bcmdhd/include/dhdioctl.h
@@ -25,7 +25,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: dhdioctl.h 303826 2011-12-20 06:02:09Z $
+ * $Id: dhdioctl.h 321498 2012-03-15 12:54:13Z $
  */
 
 #ifndef _dhdioctl_h_
@@ -85,9 +85,14 @@
 #define DHD_GLOM_VAL	0x0400
 #define DHD_EVENT_VAL	0x0800
 #define DHD_BTA_VAL	0x1000
+#if defined(NDIS630)
+#define DHD_SCAN_VAL	0x2000
+#else
 #define DHD_ISCAN_VAL	0x2000
+#endif
 #define DHD_ARPOE_VAL	0x4000
 #define DHD_REORDER_VAL	0x8000
+#define DHD_WL_VAL		0x10000
 
 #ifdef SDTEST
 /* For pktgen iovar */
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index fe10cfc..6e380ce 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -28,7 +28,7 @@
 
 #define	EPI_MAJOR_VERSION	1
 
-#define	EPI_MINOR_VERSION	9
+#define	EPI_MINOR_VERSION	23
 
 #define	EPI_RC_NUMBER		0
 
@@ -36,13 +36,13 @@
 
 #define	EPI_BUILD_NUMBER	0
 
-#define	EPI_VERSION		1, 9, 0, 0
+#define	EPI_VERSION		1, 23, 0, 0
 
-#define	EPI_VERSION_NUM		0x01090000
+#define	EPI_VERSION_NUM		0x01170000
 
-#define EPI_VERSION_DEV		1.9.0
+#define EPI_VERSION_DEV		1.23.0
 
 
-#define	EPI_VERSION_STR		"1.9 (r310571)"
+#define	EPI_VERSION_STR		"1.23 (r325707)"
 
 #endif 
diff --git a/drivers/net/wireless/bcmdhd/include/htsf.h b/drivers/net/wireless/bcmdhd/include/htsf.h
deleted file mode 100644
index d875edb..0000000
--- a/drivers/net/wireless/bcmdhd/include/htsf.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Time stamps for latency measurements 
- *
- * Copyright (C) 1999-2011, Broadcom Corporation
- * 
- *         Unless you and Broadcom execute a separate written software license
- * agreement governing use of this software, this software is licensed to you
- * under the terms of the GNU General Public License version 2 (the "GPL"),
- * available at http://www.broadcom.com/licenses/GPLv2.php, with the
- * following added to such license:
- * 
- *      As a special exception, the copyright holders of this software give you
- * permission to link this software with independent modules, and to copy and
- * distribute the resulting executable under terms of your choice, provided that
- * you also meet, for each linked independent module, the terms and conditions of
- * the license of that module.  An independent module is a module which is not
- * derived from this software.  The special exception does not apply to any
- * modifications of the software.
- * 
- *      Notwithstanding the above, under no circumstances may you combine this
- * 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: htsf.h 277737 2011-08-16 17:54:59Z $
- */
-#ifndef _HTSF_H_
-#define _HTSF_H_
-
-#define HTSFMAGIC       	0xCDCDABAB  /* in network order for tcpdump  */
-#define HTSFENDMAGIC    	0xEFEFABAB  /* to distinguish from RT2 magic */
-#define HTSF_HOSTOFFSET		102
-#define HTSF_DNGLOFFSET		HTSF_HOSTOFFSET	- 4
-#define HTSF_DNGLOFFSET2	HTSF_HOSTOFFSET	+ 106
-#define HTSF_MIN_PKTLEN 	200
-#define ETHER_TYPE_BRCM_PKTDLYSTATS     0x886d
-
-typedef enum htsfts_type {
-	T10,
-	T20,
-	T30,
-	T40,
-	T50,
-	T60,
-	T70,
-	T80,
-	T90,
-	TA0,
-	TE0
-} htsf_timestamp_t;
-
-typedef struct {
-	uint32 magic;
-	uint32 prio;
-	uint32 seqnum;
-	uint32 misc;
-	uint32 c10;
-	uint32 t10;
-	uint32 c20;
-	uint32 t20;
-	uint32 t30;
-	uint32 t40;
-	uint32 t50;
-	uint32 t60;
-	uint32 t70;
-	uint32 t80;
-	uint32 t90;
-	uint32 cA0;
-	uint32 tA0;
-	uint32 cE0;
-	uint32 tE0;
-	uint32 endmagic;
-} htsfts_t;
-
-#endif /* _HTSF_H_ */
diff --git a/drivers/net/wireless/bcmdhd/include/linux_osl.h b/drivers/net/wireless/bcmdhd/include/linux_osl.h
index e5133e0..0eacaa3 100644
--- a/drivers/net/wireless/bcmdhd/include/linux_osl.h
+++ b/drivers/net/wireless/bcmdhd/include/linux_osl.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: linux_osl.h 309193 2012-01-19 00:03:57Z $
+ * $Id: linux_osl.h 325514 2012-04-03 17:18:09Z $
  */
 
 #ifndef _linux_osl_h_
@@ -360,6 +360,42 @@
 #define	DMA_MAP(osh, va, size, direction, p, dmah) \
 	osl_dma_map((osh), (va), (size), (direction))
 
+#ifdef PKTC
+
+struct chain_node {
+	struct sk_buff	*link;
+	unsigned int	flags:3, pkts:9, bytes:20;
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+#define CHAIN_NODE(skb)		((struct chain_node*)&(((struct sk_buff*)skb)->tstamp))
+#else
+#define CHAIN_NODE(skb)		((struct chain_node*)&(((struct sk_buff*)skb)->stamp))
+#endif
+
+#define	PKTCCNT(skb)		(CHAIN_NODE(skb)->pkts)
+#define	PKTCLEN(skb)		(CHAIN_NODE(skb)->bytes)
+#define	PKTCFLAGS(skb)		(CHAIN_NODE(skb)->flags)
+#define	PKTCSETCNT(skb, c)	(CHAIN_NODE(skb)->pkts = (c) & ((1 << 9) - 1))
+#define	PKTCSETLEN(skb, l)	(CHAIN_NODE(skb)->bytes = (l) & ((1 << 20) - 1))
+#define	PKTCSETFLAG(skb, fb)	(CHAIN_NODE(skb)->flags |= (fb))
+#define	PKTCCLRFLAG(skb, fb)	(CHAIN_NODE(skb)->flags &= ~(fb))
+#define	PKTCLINK(skb)		(CHAIN_NODE(skb)->link)
+#define	PKTSETCLINK(skb, x)	(CHAIN_NODE(skb)->link = (struct sk_buff*)(x))
+#define	PKTISCHAINED(skb)	(PKTCLINK(skb) != NULL)
+#define FOREACH_CHAINED_PKT(skb, nskb) \
+	for (; (skb) != NULL; (skb) = (nskb)) \
+		if ((nskb) = PKTCLINK(skb), PKTSETCLINK((skb), NULL), 1)
+#define	PKTCFREE(osh, skb, send) \
+do { \
+	void *nskb; \
+	ASSERT((skb) != NULL); \
+	FOREACH_CHAINED_PKT((skb), nskb) { \
+		PKTFREE((osh), (skb), (send)); \
+	} \
+} while (0)
+#endif 
+
 #else 
 
 
diff --git a/drivers/net/wireless/bcmdhd/include/linuxver.h b/drivers/net/wireless/bcmdhd/include/linuxver.h
index b4f2120..e59ac88 100644
--- a/drivers/net/wireless/bcmdhd/include/linuxver.h
+++ b/drivers/net/wireless/bcmdhd/include/linuxver.h
@@ -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: linuxver.h 309909 2012-01-21 00:15:02Z $
+ * $Id: linuxver.h 315203 2012-02-16 00:58:00Z $
  */
 
 #ifndef _linuxver_h_
@@ -95,13 +95,28 @@
 #ifndef flush_scheduled_work
 #define flush_scheduled_work() flush_scheduled_tasks()
 #endif
-#endif	
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define DAEMONIZE(a) daemonize(a); \
+	allow_signal(SIGKILL); \
+	allow_signal(SIGTERM);
+#else /* Linux 2.4 (w/o preemption patch) */
+#define DAEMONIZE(a) daemonize(); \
+	do { if (a) \
+		strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a)
+	} while (0);
+#endif /* LINUX_VERSION_CODE  */
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 #define	MY_INIT_WORK(_work, _func)	INIT_WORK(_work, _func)
 #else
 #define	MY_INIT_WORK(_work, _func)	INIT_WORK(_work, _func, _work)
+#if !(LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) && defined(RHEL_MAJOR) && \
+	(RHEL_MAJOR == 5))
+
 typedef void (*work_func_t)(void *work);
+#endif
 #endif	
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
@@ -512,24 +527,7 @@
 	(tsk_ctl)->thr_pid = -1; \
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
-#define DAEMONIZE(a) daemonize(a); \
-	allow_signal(SIGKILL); \
-	allow_signal(SIGTERM);
-#else /* Linux 2.4 (w/o preemption patch) */
-#define RAISE_RX_SOFTIRQ() \
-	cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ)
-#define DAEMONIZE(a) daemonize(); \
-	do { if (a) \
-		strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \
-	} while (0);
-#endif /* LINUX_VERSION_CODE  */
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
-#define BLOCKABLE()	(!in_atomic())
-#else
-#define BLOCKABLE()	(!in_interrupt())
-#endif
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
 #define KILL_PROC(nr, sig) \
@@ -596,10 +594,11 @@
 
 #endif 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
-#define WL_DEV_IF(dev)          ((wl_if_t*)netdev_priv(dev))
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
+#define DEV_PRIV(dev)	(dev->priv)
 #else
-#define WL_DEV_IF(dev)          ((wl_if_t*)(dev)->priv)
+#define DEV_PRIV(dev)	netdev_priv(dev)
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
diff --git a/drivers/net/wireless/bcmdhd/include/osl.h b/drivers/net/wireless/bcmdhd/include/osl.h
index 0f529c7..ca171d8 100644
--- a/drivers/net/wireless/bcmdhd/include/osl.h
+++ b/drivers/net/wireless/bcmdhd/include/osl.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: osl.h 301926 2011-12-09 02:00:46Z $
+ * $Id: osl.h 320905 2012-03-13 15:33:25Z $
  */
 
 #ifndef _osl_h_
@@ -68,4 +68,21 @@
 #define OSL_SYSUPTIME_SUPPORT TRUE
 #endif 
 
+#if !defined(PKTC)
+#define	PKTCCNT(skb)		(0)
+#define	PKTCLEN(skb)		(0)
+#define	PKTCFLAGS(skb)		(0)
+#define	PKTCSETCNT(skb, c)
+#define	PKTCSETLEN(skb, l)
+#define	PKTCSETFLAG(skb, fb)
+#define	PKTCCLRFLAG(skb, fb)
+#define	PKTCLINK(skb)		PKTLINK(skb)
+#define	PKTSETCLINK(skb, x)	PKTSETLINK((skb), (x))
+#define	PKTISCHAINED(skb)	FALSE
+#define FOREACH_CHAINED_PKT(skb, nskb) \
+	for ((nskb) = NULL; (skb) != NULL; (skb) = (nskb))
+#define	PKTCFREE		PKTFREE
+#endif
+
+
 #endif	
diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11.h b/drivers/net/wireless/bcmdhd/include/proto/802.11.h
index e367493..84f8667 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/802.11.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/802.11.h
@@ -21,7 +21,7 @@
  *
  * Fundamental types and constants relating to 802.11
  *
- * $Id: 802.11.h 309193 2012-01-19 00:03:57Z $
+ * $Id: 802.11.h 320583 2012-03-12 15:09:36Z $
  */
 
 #ifndef _802_11_H_
@@ -2064,6 +2064,9 @@
 #endif
 
 #define WFA_OUI_TYPE_TPC	8
+#ifdef WLTDLS
+#define WFA_OUI_TYPE_WFD	10
+#endif 
 
 
 #define RSN_AKM_NONE		0	
@@ -2145,6 +2148,7 @@
 typedef struct dot11_timeout_ie dot11_timeout_ie_t;
 
 
+
 BWL_PRE_PACKED_STRUCT struct dot11_gtk_ie {
 	uint8 id;
 	uint8 len;
diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
index 0da2b76..5cf2f87 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
@@ -23,7 +23,7 @@
  *
  * Dependencies: proto/bcmeth.h
  *
- * $Id: bcmevent.h 294352 2011-11-06 19:23:00Z $
+ * $Id: bcmevent.h 320583 2012-03-12 15:09:36Z $
  *
  */
 
@@ -183,8 +183,11 @@
 #define WLC_E_REASSOC_IND_NDIS		86	
 #define WLC_E_ASSOC_REQ_IE 		87
 #define WLC_E_ASSOC_RESP_IE 		88
-
-#define WLC_E_LAST			89	
+#define WLC_E_ASSOC_RECREATED	89	
+#define WLC_E_ACTION_FRAME_RX_NDIS	90	
+#define WLC_E_AUTH_REQ	91		
+#define WLC_E_TDLS_PEER_EVENT 	92	
+#define WLC_E_LAST			93	
 
 
 typedef struct {
@@ -228,6 +231,7 @@
 #define WLC_E_REASON_TSPEC_REJECTED	7	
 #define WLC_E_REASON_BETTER_AP		8	
 
+
 #define WLC_E_REASON_REQUESTED_ROAM 11	
 
 
@@ -313,6 +317,11 @@
 #define WLC_E_OVL_UPDATE_IND	1	
 
 
+#define WLC_E_TDLS_PEER_DISCOVERED		0	
+#define WLC_E_TDLS_PEER_CONNECTED		1
+#define WLC_E_TDLS_PEER_DISCONNECTED	2
+
+
 #include <packed_section_end.h>
 
 #endif 
diff --git a/drivers/net/wireless/bcmdhd/include/proto/p2p.h b/drivers/net/wireless/bcmdhd/include/proto/p2p.h
index 2799640..6a0518b 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/p2p.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/p2p.h
@@ -21,7 +21,7 @@
  *
  * Fundamental types and constants relating to WFA P2P (aka WiFi Direct)
  *
- * $Id: p2p.h 281528 2011-09-02 17:13:26Z $
+ * $Id: p2p.h 311270 2012-01-28 00:11:54Z $
  */
 
 #ifndef _P2P_H_
@@ -59,6 +59,8 @@
 #define P2P_ATTR_LEN_OFF	1
 #define P2P_ATTR_DATA_OFF	3
 
+#define P2P_ATTR_ID_LEN		1	
+#define P2P_ATTR_LEN_LEN	2	
 #define P2P_ATTR_HDR_LEN	3 
 
 
@@ -79,6 +81,8 @@
 #define P2P_SEID_GROUP_INFO		14	
 #define P2P_SEID_GROUP_ID		15	
 #define P2P_SEID_P2P_IF			16	
+#define P2P_SEID_OP_CHANNEL		17	
+#define P2P_SEID_INVITE_FLAGS		18	
 #define P2P_SEID_VNDR			221	
 
 #define P2P_SE_VS_ID_SERVICES	0x1b 
@@ -129,6 +133,42 @@
 typedef struct wifi_p2p_cfg_tmo_se_s wifi_p2p_cfg_tmo_se_t;
 
 
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_listen_channel_se_s {
+	uint8	eltId;		
+	uint8	len[2];		
+	uint8	country[3];	
+	uint8	op_class;	
+	uint8	channel;	
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_listen_channel_se_s wifi_p2p_listen_channel_se_t;
+
+
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_grp_bssid_se_s {
+	uint8	eltId;		
+	uint8	len[2];		
+	uint8	mac[6];		
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_grp_bssid_se_s wifi_p2p_grp_bssid_se_t;
+
+
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_grp_id_se_s {
+	uint8	eltId;		
+	uint8	len[2];		
+	uint8	mac[6];		
+	uint8	ssid[1];	
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_grp_id_se_s wifi_p2p_grp_id_se_t;
+
+
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_intf_se_s {
+	uint8	eltId;		
+	uint8	len[2];		
+	uint8	mac[6];		
+	uint8	ifaddrs;	
+	uint8	ifaddr[1][6];	
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_intf_se_s wifi_p2p_intf_se_t;
+
 
 BWL_PRE_PACKED_STRUCT struct wifi_p2p_status_se_s {
 	uint8	eltId;		
@@ -215,6 +255,15 @@
 typedef struct wifi_p2p_chanlist_se_s wifi_p2p_chanlist_se_t;
 
 
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_pri_devtype_s {
+	uint16	cat_id;		
+	uint8	OUI[3];		
+	uint8	oui_type;	
+	uint16	sub_cat_id;	
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_pri_devtype_s wifi_p2p_pri_devtype_t;
+
+
 BWL_PRE_PACKED_STRUCT struct wifi_p2p_devinfo_se_s {
 	uint8	eltId;			
 	uint8	len[2];			
@@ -264,6 +313,23 @@
 typedef struct wifi_p2p_grpinfo_se_s wifi_p2p_grpinfo_se_t;
 
 
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_op_channel_se_s {
+	uint8	eltId;		
+	uint8	len[2];		
+	uint8	country[3];	
+	uint8	op_class;	
+	uint8	channel;	
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_op_channel_se_s wifi_p2p_op_channel_se_t;
+
+
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_invite_flags_se_s {
+	uint8	eltId;		
+	uint8	len[2];		
+	uint8	flags;		
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_invite_flags_se_s wifi_p2p_invite_flags_se_t;
+
 
 BWL_PRE_PACKED_STRUCT struct wifi_p2p_action_frame {
 	uint8	category;	
diff --git a/drivers/net/wireless/bcmdhd/include/sbchipc.h b/drivers/net/wireless/bcmdhd/include/sbchipc.h
index 8216d1e..f6e93df 100644
--- a/drivers/net/wireless/bcmdhd/include/sbchipc.h
+++ b/drivers/net/wireless/bcmdhd/include/sbchipc.h
@@ -5,7 +5,7 @@
  * JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer,
  * GPIO interface, extbus, and support for serial and parallel flashes.
  *
- * $Id: sbchipc.h 309193 2012-01-19 00:03:57Z $
+ * $Id: sbchipc.h 325465 2012-04-03 11:16:11Z $
  *
  * Copyright (C) 1999-2012, Broadcom Corporation
  * 
@@ -184,8 +184,8 @@
 
 	
 	uint32	clkdiv2;
-	uint32	PAD;
 	
+	uint32	otpcontrol1;
 	uint32	fabid;			
 
 	
@@ -515,6 +515,30 @@
 #define OTPC_PROGEN		0x80000000
 
 
+#define OTPC_40NM_PROGSEL_SHIFT	0
+#define OTPC_40NM_PCOUNT_SHIFT	1
+#define OTPC_40NM_PCOUNT_WR	0xA
+#define OTPC_40NM_PCOUNT_V1X	0xB
+#define OTPC_40NM_REGCSEL_SHIFT	5
+#define OTPC_40NM_REGCSEL_DEF	0x4
+#define OTPC_40NM_PROGIN_SHIFT	8
+#define OTPC_40NM_R2X_SHIFT	10
+#define OTPC_40NM_ODM_SHIFT	11
+#define OTPC_40NM_DF_SHIFT	15
+#define OTPC_40NM_VSEL_SHIFT	16
+#define OTPC_40NM_VSEL_WR	0xA
+#define OTPC_40NM_VSEL_V1X	0xA
+#define OTPC_40NM_VSEL_R1X	0x5
+#define OTPC_40NM_COFAIL_SHIFT	30
+
+#define OTPC1_CPCSEL_SHIFT	0
+#define OTPC1_CPCSEL_DEF	6
+#define OTPC1_TM_SHIFT		8
+#define OTPC1_TM_WR		0x84
+#define OTPC1_TM_V1X		0x84
+#define OTPC1_TM_R1X		0x4
+
+
 #define OTPP_COL_MASK		0x000000ff
 #define OTPP_COL_SHIFT		0
 #define OTPP_ROW_MASK		0x0000ff00
@@ -1437,6 +1461,10 @@
 #define CCTRL5357_NFLASH		(1<<16) 
 
 
+#define CCTRL43217_EXTPA_C0             (1<<13) 
+#define CCTRL43217_EXTPA_C1             (1<<8)  
+
+
 #define RES4328_EXT_SWITCHER_PWM	0	
 #define RES4328_BB_SWITCHER_PWM		1	
 #define RES4328_BB_SWITCHER_BURST	2	
@@ -1923,6 +1951,10 @@
 #define CCTRL_4330_SDIO_HOST_WAKE	0x00000004    
 #define CCTRL_4330_JTAG_DISABLE	0x00000008    
 
+#define PMU_VREG0_ADDR				0
+#define PMU_VREG0_DISABLE_PULLD_BT_SHIFT	2
+#define PMU_VREG0_DISABLE_PULLD_WL_SHIFT	3
+
 
 #define RES4334_LPLDO_PU		0
 #define RES4334_RESET_PULLDN_DIS	1
@@ -1981,6 +2013,10 @@
 #define CCTRL4334_HSIC_LDO_PU		(1  << 23)
 
 
+#define CCTRL1_4324_GPIO_SEL            (1 << 0)    
+#define CCTRL1_4324_SDIO_HOST_WAKE (1 << 2)  
+
+
 
 #define	RES4313_BB_PU_RSRC		0
 #define	RES4313_ILP_REQ_RSRC		1
diff --git a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h b/drivers/net/wireless/bcmdhd/include/sbpcmcia.h
index f94d82b..36ef491 100644
--- a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h
+++ b/drivers/net/wireless/bcmdhd/include/sbpcmcia.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: sbpcmcia.h 307736 2012-01-12 10:57:05Z $
+ * $Id: sbpcmcia.h 323197 2012-03-23 09:57:58Z $
  */
 
 #ifndef	_SBPCMCIA_H
diff --git a/drivers/net/wireless/bcmdhd/include/siutils.h b/drivers/net/wireless/bcmdhd/include/siutils.h
index c052eb0..ac52bc1 100644
--- a/drivers/net/wireless/bcmdhd/include/siutils.h
+++ b/drivers/net/wireless/bcmdhd/include/siutils.h
@@ -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: siutils.h 309193 2012-01-19 00:03:57Z $
+ * $Id: siutils.h 321982 2012-03-19 06:58:08Z $
  */
 
 #ifndef	_siutils_h_
@@ -189,6 +189,7 @@
 
 extern void si_watchdog(si_t *sih, uint ticks);
 extern void si_watchdog_ms(si_t *sih, uint32 ms);
+extern uint32 si_watchdog_msticks(void);
 extern void *si_gpiosetcore(si_t *sih);
 extern uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority);
 extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority);
diff --git a/drivers/net/wireless/bcmdhd/include/wlc_clm_rates.h b/drivers/net/wireless/bcmdhd/include/wlc_clm_rates.h
deleted file mode 100644
index d9061bb..0000000
--- a/drivers/net/wireless/bcmdhd/include/wlc_clm_rates.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates
- * Copyright (C) 2012, Broadcom Corporation
- * All Rights Reserved.
- * 
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
- * the contents of this file may not be disclosed to third parties, copied
- * or duplicated in any form, in whole or in part, without the prior
- * written permission of Broadcom Corporation.
- *
- * $Id: wlc_clm_rates.h 252708 2011-04-12 06:45:56Z $
- */
-
-#ifndef _WLC_CLM_RATES_H_
-#define _WLC_CLM_RATES_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-typedef enum clm_rates {
-	/************
-	 * 1 chain  *
-	 ************
-	 */
-
-	/* 1 Stream */
-	CLM_RATE_1X1_DSSS_1         = 0,
-	CLM_RATE_1X1_DSSS_2         = 1,
-	CLM_RATE_1X1_DSSS_5_5       = 2,
-	CLM_RATE_1X1_DSSS_11        = 3,
-
-	CLM_RATE_1X1_OFDM_6         = 4,
-	CLM_RATE_1X1_OFDM_9         = 5,
-	CLM_RATE_1X1_OFDM_12        = 6,
-	CLM_RATE_1X1_OFDM_18        = 7,
-	CLM_RATE_1X1_OFDM_24        = 8,
-	CLM_RATE_1X1_OFDM_36        = 9,
-	CLM_RATE_1X1_OFDM_48        = 10,
-	CLM_RATE_1X1_OFDM_54        = 11,
-
-	CLM_RATE_1X1_MCS0           = 12,
-	CLM_RATE_1X1_MCS1           = 13,
-	CLM_RATE_1X1_MCS2           = 14,
-	CLM_RATE_1X1_MCS3           = 15,
-	CLM_RATE_1X1_MCS4           = 16,
-	CLM_RATE_1X1_MCS5           = 17,
-	CLM_RATE_1X1_MCS6           = 18,
-	CLM_RATE_1X1_MCS7           = 19,
-
-	CLM_RATE_1X1_VHT0SS1        = 12,
-	CLM_RATE_1X1_VHT1SS1        = 13,
-	CLM_RATE_1X1_VHT2SS1        = 14,
-	CLM_RATE_1X1_VHT3SS1        = 15,
-	CLM_RATE_1X1_VHT4SS1        = 16,
-	CLM_RATE_1X1_VHT5SS1        = 17,
-	CLM_RATE_1X1_VHT6SS1        = 18,
-	CLM_RATE_1X1_VHT7SS1        = 19,
-	CLM_RATE_1X1_VHT8SS1        = 20,
-	CLM_RATE_1X1_VHT9SS1        = 21,
-
-
-	/************
-	 * 2 chains *
-	 ************
-	 */
-
-	/* 1 Stream expanded + 1 */
-	CLM_RATE_1X2_DSSS_1         = 22,
-	CLM_RATE_1X2_DSSS_2         = 23,
-	CLM_RATE_1X2_DSSS_5_5       = 24,
-	CLM_RATE_1X2_DSSS_11        = 25,
-
-	CLM_RATE_1X2_CDD_OFDM_6     = 26,
-	CLM_RATE_1X2_CDD_OFDM_9     = 27,
-	CLM_RATE_1X2_CDD_OFDM_12    = 28,
-	CLM_RATE_1X2_CDD_OFDM_18    = 29,
-	CLM_RATE_1X2_CDD_OFDM_24    = 30,
-	CLM_RATE_1X2_CDD_OFDM_36    = 31,
-	CLM_RATE_1X2_CDD_OFDM_48    = 32,
-	CLM_RATE_1X2_CDD_OFDM_54    = 33,
-
-	CLM_RATE_1X2_CDD_MCS0       = 34,
-	CLM_RATE_1X2_CDD_MCS1       = 35,
-	CLM_RATE_1X2_CDD_MCS2       = 36,
-	CLM_RATE_1X2_CDD_MCS3       = 37,
-	CLM_RATE_1X2_CDD_MCS4       = 38,
-	CLM_RATE_1X2_CDD_MCS5       = 39,
-	CLM_RATE_1X2_CDD_MCS6       = 40,
-	CLM_RATE_1X2_CDD_MCS7       = 41,
-
-	CLM_RATE_1X2_VHT0SS1        = 34,
-	CLM_RATE_1X2_VHT1SS1        = 35,
-	CLM_RATE_1X2_VHT2SS1        = 36,
-	CLM_RATE_1X2_VHT3SS1        = 37,
-	CLM_RATE_1X2_VHT4SS1        = 38,
-	CLM_RATE_1X2_VHT5SS1        = 39,
-	CLM_RATE_1X2_VHT6SS1        = 40,
-	CLM_RATE_1X2_VHT7SS1        = 41,
-	CLM_RATE_1X2_VHT8SS1        = 42,
-	CLM_RATE_1X2_VHT9SS1        = 43,
-
-	/* 2 Streams */
-	CLM_RATE_2X2_STBC_MCS0      = 44,
-	CLM_RATE_2X2_STBC_MCS1      = 45,
-	CLM_RATE_2X2_STBC_MCS2      = 46,
-	CLM_RATE_2X2_STBC_MCS3      = 47,
-	CLM_RATE_2X2_STBC_MCS4      = 48,
-	CLM_RATE_2X2_STBC_MCS5      = 49,
-	CLM_RATE_2X2_STBC_MCS6      = 50,
-	CLM_RATE_2X2_STBC_MCS7      = 51,
-
-	CLM_RATE_2X2_STBC_VHT0SS1   = 44,
-	CLM_RATE_2X2_STBC_VHT1SS1   = 45,
-	CLM_RATE_2X2_STBC_VHT2SS1   = 46,
-	CLM_RATE_2X2_STBC_VHT3SS1   = 47,
-	CLM_RATE_2X2_STBC_VHT4SS1   = 48,
-	CLM_RATE_2X2_STBC_VHT5SS1   = 49,
-	CLM_RATE_2X2_STBC_VHT6SS1   = 50,
-	CLM_RATE_2X2_STBC_VHT7SS1   = 51,
-	CLM_RATE_2X2_STBC_VHT8SS1   = 52,
-	CLM_RATE_2X2_STBC_VHT9SS1   = 53,
-
-	CLM_RATE_2X2_SDM_MCS8       = 54,
-	CLM_RATE_2X2_SDM_MCS9       = 55,
-	CLM_RATE_2X2_SDM_MCS10      = 56,
-	CLM_RATE_2X2_SDM_MCS11      = 57,
-	CLM_RATE_2X2_SDM_MCS12      = 58,
-	CLM_RATE_2X2_SDM_MCS13      = 59,
-	CLM_RATE_2X2_SDM_MCS14      = 60,
-	CLM_RATE_2X2_SDM_MCS15      = 61,
-
-	CLM_RATE_2X2_VHT0SS2        = 54,
-	CLM_RATE_2X2_VHT1SS2        = 55,
-	CLM_RATE_2X2_VHT2SS2        = 56,
-	CLM_RATE_2X2_VHT3SS2        = 57,
-	CLM_RATE_2X2_VHT4SS2        = 58,
-	CLM_RATE_2X2_VHT5SS2        = 59,
-	CLM_RATE_2X2_VHT6SS2        = 60,
-	CLM_RATE_2X2_VHT7SS2        = 61,
-	CLM_RATE_2X2_VHT8SS2        = 62,
-	CLM_RATE_2X2_VHT9SS2        = 63,
-
-
-	/************
-	 * 3 chains *
-	 ************
-	 */
-
-	/* 1 Stream expanded + 2 */
-	CLM_RATE_1X3_DSSS_1         = 64,
-	CLM_RATE_1X3_DSSS_2         = 65,
-	CLM_RATE_1X3_DSSS_5_5       = 66,
-	CLM_RATE_1X3_DSSS_11        = 67,
-
-	CLM_RATE_1X3_CDD_OFDM_6     = 68,
-	CLM_RATE_1X3_CDD_OFDM_9     = 69,
-	CLM_RATE_1X3_CDD_OFDM_12    = 70,
-	CLM_RATE_1X3_CDD_OFDM_18    = 71,
-	CLM_RATE_1X3_CDD_OFDM_24    = 72,
-	CLM_RATE_1X3_CDD_OFDM_36    = 73,
-	CLM_RATE_1X3_CDD_OFDM_48    = 74,
-	CLM_RATE_1X3_CDD_OFDM_54    = 75,
-
-	CLM_RATE_1X3_CDD_MCS0       = 76,
-	CLM_RATE_1X3_CDD_MCS1       = 77,
-	CLM_RATE_1X3_CDD_MCS2       = 78,
-	CLM_RATE_1X3_CDD_MCS3       = 79,
-	CLM_RATE_1X3_CDD_MCS4       = 80,
-	CLM_RATE_1X3_CDD_MCS5       = 81,
-	CLM_RATE_1X3_CDD_MCS6       = 82,
-	CLM_RATE_1X3_CDD_MCS7       = 83,
-
-	CLM_RATE_1X3_VHT0SS1        = 76,
-	CLM_RATE_1X3_VHT1SS1        = 77,
-	CLM_RATE_1X3_VHT2SS1        = 78,
-	CLM_RATE_1X3_VHT3SS1        = 79,
-	CLM_RATE_1X3_VHT4SS1        = 80,
-	CLM_RATE_1X3_VHT5SS1        = 81,
-	CLM_RATE_1X3_VHT6SS1        = 82,
-	CLM_RATE_1X3_VHT7SS1        = 83,
-	CLM_RATE_1X3_VHT8SS1        = 84,
-	CLM_RATE_1X3_VHT9SS1        = 85,
-
-	/* 2 Streams expanded + 1 */
-	CLM_RATE_2X3_STBC_MCS0      = 86,
-	CLM_RATE_2X3_STBC_MCS1      = 87,
-	CLM_RATE_2X3_STBC_MCS2      = 88,
-	CLM_RATE_2X3_STBC_MCS3      = 89,
-	CLM_RATE_2X3_STBC_MCS4      = 90,
-	CLM_RATE_2X3_STBC_MCS5      = 91,
-	CLM_RATE_2X3_STBC_MCS6      = 92,
-	CLM_RATE_2X3_STBC_MCS7      = 93,
-
-	CLM_RATE_2X3_STBC_VHT0SS1   = 86,
-	CLM_RATE_2X3_STBC_VHT1SS1   = 87,
-	CLM_RATE_2X3_STBC_VHT2SS1   = 88,
-	CLM_RATE_2X3_STBC_VHT3SS1   = 89,
-	CLM_RATE_2X3_STBC_VHT4SS1   = 90,
-	CLM_RATE_2X3_STBC_VHT5SS1   = 91,
-	CLM_RATE_2X3_STBC_VHT6SS1   = 92,
-	CLM_RATE_2X3_STBC_VHT7SS1   = 93,
-	CLM_RATE_2X3_STBC_VHT8SS1   = 94,
-	CLM_RATE_2X3_STBC_VHT9SS1   = 95,
-
-	CLM_RATE_2X3_SDM_MCS8       = 96,
-	CLM_RATE_2X3_SDM_MCS9       = 97,
-	CLM_RATE_2X3_SDM_MCS10      = 98,
-	CLM_RATE_2X3_SDM_MCS11      = 99,
-	CLM_RATE_2X3_SDM_MCS12      = 100,
-	CLM_RATE_2X3_SDM_MCS13      = 101,
-	CLM_RATE_2X3_SDM_MCS14      = 102,
-	CLM_RATE_2X3_SDM_MCS15      = 103,
-
-	CLM_RATE_2X3_VHT0SS2        = 96,
-	CLM_RATE_2X3_VHT1SS2        = 97,
-	CLM_RATE_2X3_VHT2SS2        = 98,
-	CLM_RATE_2X3_VHT3SS2        = 99,
-	CLM_RATE_2X3_VHT4SS2        = 100,
-	CLM_RATE_2X3_VHT5SS2        = 101,
-	CLM_RATE_2X3_VHT6SS2        = 102,
-	CLM_RATE_2X3_VHT7SS2        = 103,
-	CLM_RATE_2X3_VHT8SS2        = 104,
-	CLM_RATE_2X3_VHT9SS2        = 105,
-
-	/* 3 Streams */
-	CLM_RATE_3X3_SDM_MCS16      = 106,
-	CLM_RATE_3X3_SDM_MCS17      = 107,
-	CLM_RATE_3X3_SDM_MCS18      = 108,
-	CLM_RATE_3X3_SDM_MCS19      = 109,
-	CLM_RATE_3X3_SDM_MCS20      = 110,
-	CLM_RATE_3X3_SDM_MCS21      = 111,
-	CLM_RATE_3X3_SDM_MCS22      = 112,
-	CLM_RATE_3X3_SDM_MCS23      = 113,
-
-	CLM_RATE_3X3_VHT0SS3        = 106,
-	CLM_RATE_3X3_VHT1SS3        = 107,
-	CLM_RATE_3X3_VHT2SS3        = 108,
-	CLM_RATE_3X3_VHT3SS3        = 109,
-	CLM_RATE_3X3_VHT4SS3        = 110,
-	CLM_RATE_3X3_VHT5SS3        = 111,
-	CLM_RATE_3X3_VHT6SS3        = 112,
-	CLM_RATE_3X3_VHT7SS3        = 113,
-	CLM_RATE_3X3_VHT8SS3        = 114,
-	CLM_RATE_3X3_VHT9SS3        = 115,
-
-	/* Number of rate codes */
-	CLM_NUMRATES				= 116,
-	} clm_rates_t;
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _WLC_CLM_RATES_H_ */
diff --git a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
index f656a63..237c307 100644
--- a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
+++ b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
@@ -18,7 +18,7 @@
 *      Notwithstanding the above, under no circumstances may you combine this
 * 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: wlfc_proto.h 309193 2012-01-19 00:03:57Z $
+* $Id: wlfc_proto.h 322519 2012-03-21 01:15:45Z $
 *
 */
 #ifndef __wlfc_proto_definitions_h__
@@ -62,6 +62,10 @@
 	|  13  |   3  | (count, handle, prec_bmp)| One time request for packet to a specific
 	|      |      |                          | MAC destination.
 	 ---------------------------------------------------------------------------
+	|  15  |   1  | interface ID             | NIC period start
+	 ---------------------------------------------------------------------------
+	|  16  |   7  | interface ID             | NIC period end
+	 ---------------------------------------------------------------------------
 	| 255  |  N/A |  N/A                     | FILLER - This is a special type
 	|      |      |                          | that has no length or value.
 	|      |      |                          | Typically used for padding.
@@ -70,13 +74,13 @@
 
 #define WLFC_CTL_TYPE_MAC_OPEN			1
 #define WLFC_CTL_TYPE_MAC_CLOSE			2
-#define WLFC_CTL_TYPE_MAC_REQUEST_CREDIT        3
+#define WLFC_CTL_TYPE_MAC_REQUEST_CREDIT	3
 #define WLFC_CTL_TYPE_TXSTATUS			4
 #define WLFC_CTL_TYPE_PKTTAG			5
 
 #define WLFC_CTL_TYPE_MACDESC_ADD		6
 #define WLFC_CTL_TYPE_MACDESC_DEL		7
-#define WLFC_CTL_TYPE_RSSI			8
+#define WLFC_CTL_TYPE_RSSI					8
 
 #define WLFC_CTL_TYPE_INTERFACE_OPEN		9
 #define WLFC_CTL_TYPE_INTERFACE_CLOSE		10
@@ -87,25 +91,30 @@
 #define WLFC_CTL_TYPE_MAC_REQUEST_PACKET	13
 #define WLFC_CTL_TYPE_HOST_REORDER_RXPKTS	14
 
-#define WLFC_CTL_TYPE_FILLER				255
+#define WLFC_CTL_TYPE_NIC_PRD_START		15
+#define WLFC_CTL_TYPE_NIC_PRD_END		16
 
-#define WLFC_CTL_VALUE_LEN_MACDESC			8 /* handle, interface, MAC */
+#define WLFC_CTL_TYPE_FILLER			255
 
-#define WLFC_CTL_VALUE_LEN_MAC		1	/* MAC-handle */
-#define WLFC_CTL_VALUE_LEN_RSSI		1
+#define WLFC_CTL_VALUE_LEN_MACDESC		8	/* handle, interface, MAC */
 
-#define WLFC_CTL_VALUE_LEN_INTERFACE	1
+#define WLFC_CTL_VALUE_LEN_MAC			1	/* MAC-handle */
+#define WLFC_CTL_VALUE_LEN_RSSI			1
+
+#define WLFC_CTL_VALUE_LEN_INTERFACE		1
 #define WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP	2
 
-#define WLFC_CTL_VALUE_LEN_TXSTATUS	4
-#define WLFC_CTL_VALUE_LEN_PKTTAG	4
+#define WLFC_CTL_VALUE_LEN_TXSTATUS		4
+#define WLFC_CTL_VALUE_LEN_PKTTAG		4
 
 /* enough space to host all 4 ACs, bc/mc and atim fifo credit */
 #define WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK	6
 
-#define WLFC_CTL_VALUE_LEN_REQUEST_CREDIT 3 /* credit, MAC-handle, prec_bitmap */
-#define WLFC_CTL_VALUE_LEN_REQUEST_PACKET 3 /* credit, MAC-handle, prec_bitmap */
+#define WLFC_CTL_VALUE_LEN_REQUEST_CREDIT	3	/* credit, MAC-handle, prec_bitmap */
+#define WLFC_CTL_VALUE_LEN_REQUEST_PACKET	3	/* credit, MAC-handle, prec_bitmap */
 
+#define WLFC_CTL_VALUE_LEN_NIC_PRD_START	1
+#define WLFC_CTL_VALUE_LEN_NIC_PRD_END		7
 
 
 #define WLFC_PKTID_GEN_MASK		0x80000000
diff --git a/drivers/net/wireless/bcmdhd/include/wlioctl.h b/drivers/net/wireless/bcmdhd/include/wlioctl.h
index e2ba244..13cf76d 100644
--- a/drivers/net/wireless/bcmdhd/include/wlioctl.h
+++ b/drivers/net/wireless/bcmdhd/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 310294 2012-01-24 06:17:47Z $
+ * $Id: wlioctl.h 325538 2012-04-03 19:46:57Z $
  */
 
 #ifndef _wlioctl_h_
@@ -35,7 +35,8 @@
 #include <proto/bcmeth.h>
 #include <proto/bcmevent.h>
 #include <proto/802.11.h>
-#include <bcmwifi.h>
+#include <bcmwifi_channels.h>
+#include <bcmwifi_rates.h>
 
 #include <bcm_mpool_pub.h>
 #include <bcmcdc.h>
@@ -194,6 +195,7 @@
 
 	uint8		n_cap;			/* BSS is 802.11N Capable */
 	uint32		nbss_cap;		/* 802.11N BSS Capabilities (based on HT_CAP_*) */
+	uint32		vbss_cap;		/* 802.11AC BSS Capabilities (based on VHT_CAP) */
 	uint8		ctl_ch;			/* 802.11N BSS control channel number */
 	uint8		padding1[3];		/* explicit struct alignment padding */
 	uint16		vht_rxmcsmap;		/* VHT rx mcs map */
@@ -469,15 +471,15 @@
 	struct ether_addr mac;
 } wl_probe_params_t;
 
-#define WL_NUMRATES		16	/* max # of rates in a rateset */
+#define WL_MAXRATES_IN_SET		16	/* max # of rates in a rateset */
 typedef struct wl_rateset {
 	uint32	count;			/* # rates in this set */
-	uint8	rates[WL_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
+	uint8	rates[WL_MAXRATES_IN_SET];	/* rates in 500kbps units w/hi bit set if basic */
 } wl_rateset_t;
 
 typedef struct wl_rateset_args {
 	uint32	count;			/* # rates in this set */
-	uint8	rates[WL_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
+	uint8	rates[WL_MAXRATES_IN_SET];	/* rates in 500kbps units w/hi bit set if basic */
 	uint8   mcs[MCSSET_LEN];        /* supported mcs index bit map */
 } wl_rateset_args_t;
 
@@ -908,6 +910,12 @@
 #define MFP_SHA256		0x0800 /* a special configuration for STA for WIFI test tool */
 #endif /* MFP */
 
+#ifdef MFP
+#define MFP_CAPABLE		0x0200
+#define MFP_REQUIRED	0x0400
+#define MFP_SHA256		0x0800 /* a special configuration for STA for WIFI test tool */
+#endif /* MFP */
+
 /* WPA authentication mode bitvec */
 #define WPA_AUTH_DISABLED	0x0000	/* Legacy (i.e., non-WPA) */
 #define WPA_AUTH_NONE		0x0001	/* none (IBSS) */
@@ -1145,9 +1153,6 @@
 	int isvalid;            /* Flag indicating whether above data is valid */
 } wl_lq_t; /* Link Quality */
 
-/* NINTENDO2 */
-#define MCS_INDEX_SIZE                  33
-
 typedef enum wl_wakeup_reason_type {
 	LCD_ON = 1,
 	LCD_OFF,
@@ -1174,7 +1179,8 @@
 /* Get MAC rate histogram response */
 typedef struct {
 	uint32	rate[WLC_MAXRATE + 1];	/* Rates */
-	uint32	mcs_index[MCS_INDEX_SIZE];	/* MCS index */
+	uint32	mcs[WL_RATESET_SZ_HT_MCS * WL_TX_CHAINS_MAX];	/* MCS counts */
+	uint32	vht[WL_RATESET_SZ_VHT_MCS][WL_TX_CHAINS_MAX];	/* VHT counts */
 	uint32	tsf_timer[2][2];	/* Start and End time for 8bytes value */
 } wl_mac_ratehisto_res_t;	/* MAC Specific Rate Histogram Response */
 
@@ -1754,6 +1760,7 @@
 #define	WLC_PHY_TYPE_HT		7
 #define	WLC_PHY_TYPE_LCN	8
 #define	WLC_PHY_TYPE_LCN40	10
+#define WLC_PHY_TYPE_AC		11
 #define	WLC_PHY_TYPE_NULL	0xf
 
 /* MAC list modes */
@@ -1823,11 +1830,25 @@
 #define WLC_N_PREAMBLE_GF		1
 #define WLC_N_PREAMBLE_GF_BRCM          2
 
-/* values for band specific 40MHz capabilities */
+/* values for band specific 40MHz capabilities (deprecated) */
 #define WLC_N_BW_20ALL			0
 #define WLC_N_BW_40ALL			1
 #define WLC_N_BW_20IN2G_40IN5G		2
 
+#define WLC_BW_20MHZ_BIT		(1<<0)
+#define WLC_BW_40MHZ_BIT		(1<<1)
+#define WLC_BW_80MHZ_BIT		(1<<2)
+
+/* Bandwidth capabilities */
+#define WLC_BW_CAP_20MHZ		(WLC_BW_20MHZ_BIT)
+#define WLC_BW_CAP_40MHZ		(WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT)
+#define WLC_BW_CAP_80MHZ		(WLC_BW_80MHZ_BIT|WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT)
+#define WLC_BW_CAP_UNRESTRICTED		0xFF
+
+#define WL_BW_CAP_20MHZ(bw_cap)	(((bw_cap) & WLC_BW_20MHZ_BIT) ? TRUE : FALSE)
+#define WL_BW_CAP_40MHZ(bw_cap)	(((bw_cap) & WLC_BW_40MHZ_BIT) ? TRUE : FALSE)
+#define WL_BW_CAP_80MHZ(bw_cap)	(((bw_cap) & WLC_BW_80MHZ_BIT) ? TRUE : FALSE)
+
 /* values to force tx/rx chain */
 #define WLC_N_TXRX_CHAIN0		0
 #define WLC_N_TXRX_CHAIN1		1
@@ -1835,6 +1856,7 @@
 /* bitflags for SGI support (sgi_rx iovar) */
 #define WLC_N_SGI_20			0x01
 #define WLC_N_SGI_40			0x02
+#define WLC_AC_SGI_80			0x04
 
 /* when sgi_tx==WLC_SGI_ALL, bypass rate selection, enable sgi for all mcs */
 #define WLC_SGI_ALL				0x02
@@ -1975,13 +1997,21 @@
 	uint16 thresh1_20_lo;	/* Radar detection, thresh 1 (range 5250-5350MHz) for BW 20MHz */
 	uint16 thresh0_40_lo;	/* Radar detection, thresh 0 (range 5250-5350MHz) for BW 40MHz */
 	uint16 thresh1_40_lo;	/* Radar detection, thresh 1 (range 5250-5350MHz) for BW 40MHz */
+	uint16 thresh0_80_lo;	/* Radar detection, thresh 0 (range 5250-5350MHz) for BW 80MHz */
+	uint16 thresh1_80_lo;	/* Radar detection, thresh 1 (range 5250-5350MHz) for BW 80MHz */
+	uint16 thresh0_160_lo;	/* Radar detection, thresh 0 (range 5250-5350MHz) for BW 160MHz */
+	uint16 thresh1_160_lo;	/* Radar detection, thresh 1 (range 5250-5350MHz) for BW 160MHz */
 	uint16 thresh0_20_hi;	/* Radar detection, thresh 0 (range 5470-5725MHz) for BW 20MHz */
 	uint16 thresh1_20_hi;	/* Radar detection, thresh 1 (range 5470-5725MHz) for BW 20MHz */
 	uint16 thresh0_40_hi;	/* Radar detection, thresh 0 (range 5470-5725MHz) for BW 40MHz */
 	uint16 thresh1_40_hi;	/* Radar detection, thresh 1 (range 5470-5725MHz) for BW 40MHz */
+	uint16 thresh0_80_hi;	/* Radar detection, thresh 0 (range 5470-5725MHz) for BW 80MHz */
+	uint16 thresh1_80_hi;	/* Radar detection, thresh 1 (range 5470-5725MHz) for BW 80MHz */
+	uint16 thresh0_160_hi;	/* Radar detection, thresh 0 (range 5470-5725MHz) for BW 160MHz */
+	uint16 thresh1_160_hi;	/* Radar detection, thresh 1 (range 5470-5725MHz) for BW 160MHz */
 } wl_radar_thr_t;
 
-#define WL_RADAR_THR_VERSION	1
+#define WL_RADAR_THR_VERSION	2
 #define WL_THRESHOLD_LO_BAND	70	/* range from 5250MHz - 5350MHz */
 
 /* radar iovar SET defines */
@@ -2085,6 +2115,7 @@
 #define WL_NUM_RATES_OFDM			8 /* 6, 9, 12, 18, 24, 36, 48, 54 Mbps SISO/CDD */
 #define WL_NUM_RATES_MCS_1STREAM	8 /* MCS 0-7 1-stream rates - SISO/CDD/STBC/MCS */
 #define WL_NUM_RATES_EXTRA_VHT		2 /* Additional VHT 11AC rates */
+#define WL_NUM_RATES_VHT			10
 #define WL_NUM_RATES_MCS32			1
 
 #define WLC_NUM_RATES_CCK       WL_NUM_RATES_CCK
@@ -2464,7 +2495,6 @@
 
 #define WL_TXPPR_VERSION	0
 #define WL_TXPPR_LENGTH	(sizeof(wl_txppr_t))
-#define WL_CLM_NUM_RATES	116		/* must be the same as CLM_NUMRATES */
 #define TX_POWER_T_VERSION	43
 
 /* Defines used with channel_bandwidth for curpower */
@@ -2472,6 +2502,20 @@
 #define WL_BW_40MHZ 		1
 #define WL_BW_80MHZ 		2
 
+/* tx_power_t.flags bits */
+#ifdef PPR_API
+#define WL_TX_POWER2_F_ENABLED	1
+#define WL_TX_POWER2_F_HW		2
+#define WL_TX_POWER2_F_MIMO		4
+#define WL_TX_POWER2_F_SISO		8
+#define WL_TX_POWER2_F_HT		0x10
+#else
+#define WL_TX_POWER_F_ENABLED	1
+#define WL_TX_POWER_F_HW		2
+#define WL_TX_POWER_F_MIMO		4
+#define WL_TX_POWER_F_SISO		8
+#define WL_TX_POWER_F_HT		0x10
+#endif
 typedef struct {
 	uint32 flags;
 	chanspec_t chanspec;			/* txpwr report for this channel */
@@ -2490,13 +2534,18 @@
 	uint8 user_limit[WL_TX_POWER_RATES];	/* User limit */
 	int8 board_limit[WL_TX_POWER_RATES];	/* Max power board can support (SROM) */
 	int8 target[WL_TX_POWER_RATES];			/* Latest target power */
-	int8 clm_limits[WL_CLM_NUM_RATES];		/* regulatory limits - 20, 40 or 80MHz */
-	int8 clm_limits_subchan1[WL_CLM_NUM_RATES];	/* regulatory limits - 20in40 or 40in80 */
-	int8 clm_limits_subchan2[WL_CLM_NUM_RATES];	/* regulatory limits - 20in80MHz */
+	int8 clm_limits[WL_NUMRATES];		/* regulatory limits - 20, 40 or 80MHz */
+	int8 clm_limits_subchan1[WL_NUMRATES];	/* regulatory limits - 20in40 or 40in80 */
+	int8 clm_limits_subchan2[WL_NUMRATES];	/* regulatory limits - 20in80MHz */
 	int8 sar;					/* SAR limit for display by wl executable */
 	int8 channel_bandwidth;		/* 20, 40 or 80 MHz bandwidth? */
 	uint8 version;				/* Version of the data format wlu <--> driver */
+	uint8 display_core;			/* Displayed curpower core */
+#ifdef PPR_API
+} tx_power_new_t;
+#else
 } tx_power_t;
+#endif
 
 typedef struct tx_inst_power {
 	uint8 txpwr_est_Pout[2];			/* Latest estimate for 2.4 and 5 Ghz */
@@ -2638,6 +2687,8 @@
 #define WL_MCNX_VAL		0x00002000
 #define WL_PROT_VAL		0x00004000
 #define WL_PSTA_VAL		0x00008000
+#define WL_TBTT_VAL		0x00010000
+#define WL_NIC_VAL		0x00020000
 /* use top-bit for WL_TIME_STAMP_VAL because this is a modifier
  * rather than a message-type of its own
  */
@@ -2678,7 +2729,9 @@
 
 /* maximum channels returned by the get valid channels iovar */
 #define WL_NUMCHANNELS		64
-#define WL_NUMCHANSPECS		100
+
+/* max number of chanspecs (used by the iovar to calc. buf space) */
+#define WL_NUMCHANSPECS 110
 
 /* WDS link local endpoint WPA role */
 #define WL_WDS_WPA_ROLE_AUTH	0	/* authenticator */
@@ -3445,6 +3498,18 @@
 	chanspec_t chanspec;
 	uint32 pad;			/* future */
 } tdls_iovar_t;
+
+/* modes */
+#define TDLS_WFD_IE_TX 0
+#define TDLS_WFD_IE_RX 1
+#define TDLS_WFD_IE_SIZE 255
+/* structure for tdls wfd ie */
+typedef struct tdls_wfd_ie_iovar {
+	struct ether_addr ea;		/* Station address */
+	uint8 mode;
+	uint8 length;
+	uint8 data[TDLS_WFD_IE_SIZE];
+} tdls_wfd_ie_iovar_t;
 #endif /* WLTDLS */
 
 /* structure for addts/delts arguments */
@@ -3492,6 +3557,9 @@
 #define TSPEC_DEFAULT_SBW_FACTOR	0x3000	/* default surplus bw */
 
 
+#define WL_WOWL_KEEPALIVE_MAX_PACKET_SIZE  80
+#define WLC_WOWL_MAX_KEEPALIVE	2
+
 /* define for flag */
 #define TSPEC_PENDING		0	/* TSPEC pending */
 #define TSPEC_ACCEPTED		1	/* TSPEC accepted */
@@ -3541,6 +3609,8 @@
 #define WLC_ROAM_TRIGGER_AUTO		3 /* auto-detect environment */
 #define WLC_ROAM_TRIGGER_MAX_VALUE	3 /* max. valid value */
 
+#define WLC_ROAM_NEVER_ROAM_TRIGGER	(-100) /* Avoid Roaming by setting a large value */
+
 /* Preferred Network Offload (PNO, formerly PFN) defines */
 #define WPA_AUTH_PFN_ANY	0xffffffff	/* for PFN, match only ssid */
 
@@ -3879,27 +3949,37 @@
 	uint16 rxpktcnt[NUM_80211_RATES+1];
 } wl_pkteng_stats_t;
 
-#define WL_WOWL_MAGIC	(1 << 0)	/* Wakeup on Magic packet */
-#define WL_WOWL_NET	(1 << 1)	/* Wakeup on Netpattern */
-#define WL_WOWL_DIS	(1 << 2)	/* Wakeup on loss-of-link due to Disassoc/Deauth */
-#define WL_WOWL_RETR	(1 << 3)	/* Wakeup on retrograde TSF */
-#define WL_WOWL_BCN	(1 << 4)	/* Wakeup on loss of beacon */
-#define WL_WOWL_TST	(1 << 5)	/* Wakeup after test */
-#define WL_WOWL_M1      (1 << 6)        /* Wakeup after PTK refresh */
-#define WL_WOWL_EAPID   (1 << 7)        /* Wakeup after receipt of EAP-Identity Req */
-#define WL_WOWL_PME_GPIO (1 << 8)   /* Wakeind via PME(0) or GPIO(1) */
-#define WL_WOWL_KEYROT  (1 << 14)       /* If the bit is set, use key rotaton */
-#define WL_WOWL_BCAST	(1 << 15)	/* If the bit is set, frm received was bcast frame */
 
-#define MAGIC_PKT_MINLEN 102	/* Magic pkt min length is 6 * 0xFF + 16 * ETHER_ADDR_LEN */
+#define WL_WOWL_MAGIC       (1 << 0)    /* Wakeup on Magic packet */
+#define WL_WOWL_NET         (1 << 1)    /* Wakeup on Netpattern */
+#define WL_WOWL_DIS         (1 << 2)    /* Wakeup on loss-of-link due to Disassoc/Deauth */
+#define WL_WOWL_RETR        (1 << 3)    /* Wakeup on retrograde TSF */
+#define WL_WOWL_BCN         (1 << 4)    /* Wakeup on loss of beacon */
+#define WL_WOWL_TST         (1 << 5)    /* Wakeup after test */
+#define WL_WOWL_M1          (1 << 6)    /* Wakeup after PTK refresh */
+#define WL_WOWL_EAPID       (1 << 7)    /* Wakeup after receipt of EAP-Identity Req */
+#define WL_WOWL_PME_GPIO    (1 << 8)    /* Wakeind via PME(0) or GPIO(1) */
+#define WL_WOWL_NEEDTKIP1   (1 << 9)    /* need tkip phase 1 key to be updated by the driver */
+#define WL_WOWL_GTK_FAILURE (1 << 10)   /* enable wakeup if GTK fails */
+#define WL_WOWL_EXTMAGPAT   (1 << 11)   /* support extended magic packets */
+#define WL_WOWL_ARPOFFLOAD  (1 << 12)   /* support ARP/NS/keepalive offloading */
+#define WL_WOWL_WPA2        (1 << 13)   /* read protocol version for EAPOL frames */
+#define WL_WOWL_KEYROT      (1 << 14)   /* If the bit is set, use key rotaton */
+#define WL_WOWL_BCAST       (1 << 15)   /* If the bit is set, frm received was bcast frame */
+
+#define MAGIC_PKT_MINLEN 102    /* Magic pkt min length is 6 * 0xFF + 16 * ETHER_ADDR_LEN */
+
+#define WOWL_PATTEN_TYPE_ARP	(1 << 0)	/* ARP offload Pattern */
+#define WOWL_PATTEN_TYPE_NA		(1 << 1)	/* NA offload Pattern */
 
 typedef struct {
-	uint masksize;		/* Size of the mask in #of bytes */
-	uint offset;		/* Offset to start looking for the packet in # of bytes */
-	uint patternoffset;	/* Offset of start of pattern in the structure */
-	uint patternsize;	/* Size of the pattern itself in #of bytes */
-	ulong id;		/* id */
-	uint reasonsize;	/* Size of the wakeup reason code */
+	uint32 masksize;		/* Size of the mask in #of bytes */
+	uint32 offset;			/* Offset to start looking for the packet in # of bytes */
+	uint32 patternoffset;	/* Offset of start of pattern in the structure */
+	uint32 patternsize;		/* Size of the pattern itself in #of bytes */
+	uint32 id;				/* id */
+	uint32 reasonsize;		/* Size of the wakeup reason code */
+	uint32 flags;			/* Flags to tell the pattern type and other properties */
 	/* Mask follows the structure above */
 	/* Pattern follows the mask is at 'patternoffset' from the start */
 } wl_wowl_pattern_t;
@@ -3914,6 +3994,7 @@
 	uint16	ucode_wakeind;	/* What wakeup-event indication was set by ucode */
 } wl_wowl_wakeind_t;
 
+
 /* per AC rate control related data structure */
 typedef struct wl_txrate_class {
 	uint8		init_rate;
@@ -4395,6 +4476,13 @@
 #define	AP_TPC_AP_BSS_PWR	3	/* Both AP and BSS power control */
 #define AP_TPC_MAX_LINK_MARGIN	127
 
+/* ap tpc modes */
+#define	AP_TPC_OFF		0
+#define	AP_TPC_BSS_PWR		1	/* BSS power control */
+#define AP_TPC_AP_PWR		2	/* AP power control */
+#define	AP_TPC_AP_BSS_PWR	3	/* Both AP and BSS power control */
+#define AP_TPC_MAX_LINK_MARGIN	127
+
 /* structure/defines for selective mgmt frame (smf) stats support */
 
 #define SMFS_VERSION 1
@@ -4791,4 +4879,102 @@
 } wl_mempool_stats_t;
 
 
+/* D0 Coalescing */
+#define IPV4_ARP_FILTER		0x0001
+#define IPV4_NETBT_FILTER	0x0002
+#define IPV4_LLMNR_FILTER	0x0004
+#define IPV4_SSDP_FILTER	0x0008
+#define IPV4_WSD_FILTER		0x0010
+#define IPV6_NETBT_FILTER	0x0200
+#define IPV6_LLMNR_FILTER	0x0400
+#define IPV6_SSDP_FILTER	0x0800
+#define IPV6_WSD_FILTER		0x1000
+
+/* Network Offload Engine */
+#define NWOE_OL_ENABLE		0x00000001
+
+typedef struct {
+	uint32 ipaddr;
+	uint32 ipaddr_netmask;
+	uint32 ipaddr_gateway;
+} nwoe_ifconfig_t;
+
+/*
+ * Traffic management structures/defines.
+ */
+
+/* Traffic management bandwidth	parameters */
+#define	TRF_MGMT_MAX_PRIORITIES		3
+
+#define	TRF_MGMT_FLAG_ADD_DSCP		0x0001	/* Add DSCP	to IP TOS field	*/
+#define	TRF_MGMT_FLAG_DISABLE_SHAPING	0x0002	/* Only	support	traffic	clasification */
+
+
+/* Traffic management priority classes */
+typedef	enum trf_mgmt_priority_class {
+	trf_mgmt_priority_low		= 0,	/* Maps	to 802.1p BK */
+	trf_mgmt_priority_medium	= 1,	/* Maps	to 802.1p BE */
+	trf_mgmt_priority_high		= 2,	/* Maps	to 802.1p VI */
+	trf_mgmt_priority_invalid	= (trf_mgmt_priority_high + 1)
+} trf_mgmt_priority_class_t;
+
+/* Traffic management configuration parameters */
+typedef	struct trf_mgmt_config {
+	uint32	trf_mgmt_enabled;				/* 0 - disabled, 1 - enabled */
+	uint32	flags;						/* See TRF_MGMT_FLAG_xxx defines */
+	uint32	host_ip_addr;
+	uint32	host_subnet_mask;
+	uint32	downlink_bandwidth;				/* In units of kbps */
+	uint32	uplink_bandwidth;				/* In units of kbps */
+	uint32	min_tx_bandwidth[TRF_MGMT_MAX_PRIORITIES];
+	uint32	min_rx_bandwidth[TRF_MGMT_MAX_PRIORITIES];
+} trf_mgmt_config_t;
+
+/* Traffic management filter */
+typedef	struct trf_mgmt_filter {
+	uint32	dst_ip_addr;	/* His IP address */
+	uint16	dst_port;	/* His L4 port */
+	uint16	src_port;	/* My L4 port */
+	uint16	prot;		/* L4 protocol (only TCP or UDP protocols) */
+	uint16	flags;		/* TBD.	For	now, this must be zero.	*/
+	trf_mgmt_priority_class_t priority;	/* 802.1p priority for filtered	packets	*/
+} trf_mgmt_filter_t;
+
+/* Traffic management filter list (variable length)	*/
+typedef	struct trf_mgmt_filter_list	{
+	uint32		    num_filters;
+	trf_mgmt_filter_t   filter[1];
+} trf_mgmt_filter_list_t;
+
+/* Traffic management shaping info */
+typedef	struct trf_mgmt_shaping_info {
+	uint32	max_bps;			/* Max bytes consumed or produced per second */
+	uint32	max_bytes_per_sampling_period;	/* Max bytes consumed or produced per sample */
+	uint32	shaping_delay_threshold;	/* Theshold for starting traffic delays	 */
+	uint32	num_bytes_produced_per_sec;	/* Bytes produced over the sampling period */
+	uint32	num_bytes_consumed_per_sec;	/* Bytes consumed over the sampling period */
+} trf_mgmt_shaping_info_t;
+
+/* Traffic management shaping info array */
+typedef	struct trf_mgmt_shaping_info_array {
+	trf_mgmt_shaping_info_t	   tx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES];
+	trf_mgmt_shaping_info_t	   rx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES];
+} trf_mgmt_shaping_info_array_t;
+
+
+/* Traffic management statistical counters */
+typedef	struct trf_mgmt_stats {
+	uint32	num_processed_packets;	/* Number of packets processed */
+	uint32	num_processed_bytes;	/* Number of bytes processed */
+	uint32	num_queued_packets;	/* Number of packets in	queue */
+	uint32	num_queued_bytes;	/* Number of bytes in queue	*/
+	uint32	num_discarded_packets;	/* Number of packets discarded from queue */
+} trf_mgmt_stats_t;
+
+/* Traffic management statisics	array */
+typedef	struct trf_mgmt_stats_array	{
+	trf_mgmt_stats_t    tx_queue_stats[TRF_MGMT_MAX_PRIORITIES];
+	trf_mgmt_stats_t    rx_queue_stats[TRF_MGMT_MAX_PRIORITIES];
+} trf_mgmt_stats_array_t;
+
 #endif /* _wlioctl_h_ */
diff --git a/drivers/net/wireless/bcmdhd/linux_osl.c b/drivers/net/wireless/bcmdhd/linux_osl.c
index 5cc3a87..ef9c733 100644
--- a/drivers/net/wireless/bcmdhd/linux_osl.c
+++ b/drivers/net/wireless/bcmdhd/linux_osl.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: linux_osl.c 309193 2012-01-19 00:03:57Z $
+ * $Id: linux_osl.c 311099 2012-01-27 14:46:59Z $
  */
 
 #define LINUX_PORT
diff --git a/drivers/net/wireless/bcmdhd/sbutils.c b/drivers/net/wireless/bcmdhd/sbutils.c
index bc42a2b..68cfcb2 100644
--- a/drivers/net/wireless/bcmdhd/sbutils.c
+++ b/drivers/net/wireless/bcmdhd/sbutils.c
@@ -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: sbutils.c 300516 2011-12-04 17:39:44Z $
+ * $Id: sbutils.c 310902 2012-01-26 19:45:33Z $
  */
 
 #include <bcm_cfg.h>
diff --git a/drivers/net/wireless/bcmdhd/siutils.c b/drivers/net/wireless/bcmdhd/siutils.c
index 5cfb54e..2d2b7db 100644
--- a/drivers/net/wireless/bcmdhd/siutils.c
+++ b/drivers/net/wireless/bcmdhd/siutils.c
@@ -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: siutils.c 309908 2012-01-21 00:14:29Z $
+ * $Id: siutils.c 323774 2012-03-27 00:16:45Z $
  */
 
 #include <bcm_cfg.h>
@@ -1131,6 +1131,11 @@
 	si_watchdog(sih, wd_msticks * ms);
 }
 
+uint32 si_watchdog_msticks(void)
+{
+	return wd_msticks;
+}
+
 bool
 si_taclear(si_t *sih, bool details)
 {
@@ -1935,6 +1940,10 @@
 	uint32 coreinfo;
 	uint memsize = 0;
 
+	if ((CHIPID(sih->chip) == BCM4334_CHIP_ID) && (CHIPREV(sih->chiprev) < 2)) {
+		return (32 * 1024);
+	}
+
 	sii = SI_INFO(sih);
 
 	/* Block ints and save current core */
diff --git a/drivers/net/wireless/bcmdhd/uamp_api.h b/drivers/net/wireless/bcmdhd/uamp_api.h
index c51c68c..673dce0 100644
--- a/drivers/net/wireless/bcmdhd/uamp_api.h
+++ b/drivers/net/wireless/bcmdhd/uamp_api.h
@@ -3,9 +3,9 @@
  *
  *  Description: Universal AMP API
  *
- * Copyright (C) 1999-2011, Broadcom Corporation
+ * Copyright (C) 1999-2012, Broadcom Corporation
  * 
- *         Unless you and Broadcom execute a separate written software license
+ *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
  * under the terms of the GNU General Public License version 2 (the "GPL"),
  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
@@ -23,7 +23,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: uamp_api.h,v 1.2.8.1 2011-02-05 00:16:14 Exp $
+ * $Id: uamp_api.h 294267 2011-11-04 23:41:52Z $
  *
  */
 #ifndef UAMP_API_H
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 65f8912..850694f 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.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_android.c 309571 2012-01-20 01:45:10Z $
+ * $Id: wl_android.c 323797 2012-03-27 01:27:20Z $
  */
 
 #include <linux/module.h>
@@ -73,7 +73,6 @@
 #define CMD_GETBAND		"GETBAND"
 #define CMD_COUNTRY		"COUNTRY"
 #define CMD_P2P_SET_NOA		"P2P_SET_NOA"
-#define CMD_P2P_GET_NOA		"P2P_GET_NOA"
 #define CMD_P2P_SET_PS		"P2P_SET_PS"
 #define CMD_SET_AP_WPS_P2P_IE 		"SET_AP_WPS_P2P_IE"
 
@@ -128,6 +127,10 @@
 #endif
 extern int dhd_os_check_if_up(void *dhdp);
 extern void *bcmsdh_get_drvdata(void);
+#ifdef PROP_TXSTATUS
+extern int dhd_wlfc_init(dhd_pub_t *dhd);
+extern void dhd_wlfc_deinit(dhd_pub_t *dhd);
+#endif
 
 extern bool ap_fw_loaded;
 #ifdef CUSTOMER_HW2
@@ -378,6 +381,9 @@
 		ret = dhd_dev_reset(dev, FALSE);
 		sdioh_start(NULL, 1);
 		dhd_dev_init_ioctl(dev);
+#ifdef PROP_TXSTATUS
+		dhd_wlfc_init(bcmsdh_get_drvdata());
+#endif
 		g_wifi_on = TRUE;
 	}
 
@@ -399,6 +405,9 @@
 
 	dhd_net_if_lock(dev);
 	if (g_wifi_on) {
+#ifdef PROP_TXSTATUS
+		dhd_wlfc_deinit(bcmsdh_get_drvdata());
+#endif
 		dhd_dev_reset(dev, 1);
 		sdioh_stop(NULL);
 		dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
@@ -551,9 +560,6 @@
 		bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip,
 			priv_cmd.total_len - skip);
 	}
-	else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) {
-		bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len);
-	}
 	else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) {
 		int skip = strlen(CMD_P2P_SET_PS) + 1;
 		bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip,
@@ -574,9 +580,9 @@
 	}
 
 	if (bytes_written >= 0) {
-		if (bytes_written == 0)
+		if ((bytes_written == 0) && (priv_cmd.total_len > 0))
 			command[0] = '\0';
-		if (bytes_written > priv_cmd.total_len) {
+		if (bytes_written >= priv_cmd.total_len) {
 			DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written));
 			bytes_written = priv_cmd.total_len;
 		} else {
@@ -605,7 +611,6 @@
 {
 	int ret = 0;
 
-	dhd_msg_level = DHD_ERROR_VAL;
 #ifdef ENABLE_INSMOD_NO_FW_LOAD
 	dhd_download_fw_on_driverload = FALSE;
 #endif /* ENABLE_INSMOD_NO_FW_LOAD */
@@ -683,13 +688,14 @@
 		alloc_ptr = wifi_control_data->mem_prealloc(section, size);
 		if (alloc_ptr) {
 			DHD_INFO(("success alloc section %d\n", section));
-			bzero(alloc_ptr, size);
+			if (size != 0L)
+				bzero(alloc_ptr, size);
 			return alloc_ptr;
 		}
 	}
 
 	DHD_ERROR(("can't alloc section %d\n", section));
-	return 0;
+	return NULL;
 }
 
 int wifi_get_irq_number(unsigned long *irq_flags_ptr)
@@ -712,7 +718,7 @@
 		wifi_control_data->set_power(on);
 	}
 	if (msec)
-		mdelay(msec);
+		msleep(msec);
 	return 0;
 }
 
@@ -761,7 +767,6 @@
 		wifi_irqres = platform_get_resource_byname(pdev,
 			IORESOURCE_IRQ, "bcm4329_wlan_irq");
 	wifi_control_data = wifi_ctrl;
-
 	wifi_set_power(1, 0);	/* Power On */
 	wifi_set_carddetect(1);	/* CardDetect (0->1) */
 
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index ed0533b..c6ebfa7 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.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_cfg80211.c 310409 2012-01-24 18:47:09Z $
+ * $Id: wl_cfg80211.c 323022 2012-03-22 17:48:58Z $
  */
 
 #include <typedefs.h>
@@ -30,7 +30,7 @@
 #include <linux/kernel.h>
 
 #include <bcmutils.h>
-#include <bcmwifi.h>
+#include <bcmwifi_channels.h>
 #include <bcmendian.h>
 #include <proto/ethernet.h>
 #include <proto/802.11.h>
@@ -95,6 +95,7 @@
 
 
 static struct device *cfg80211_parent_dev = NULL;
+static int vsdb_supported = 0;
 struct wl_priv *wlcfg_drv_priv = NULL;
 
 u32 wl_dbg_level = WL_DBG_ERR;
@@ -104,6 +105,7 @@
 #define MAX_WAIT_TIME 1500
 #define WL_SCAN_ACTIVE_TIME	 40 /* ms : Embedded default Active setting from DHD Driver */
 #define WL_SCAN_PASSIVE_TIME	130 /* ms: Embedded default Passive setting from DHD Driver */
+#define WL_FRAME_LEN			300
 
 #define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL
 
@@ -111,11 +113,6 @@
 #define DNGL_FUNC(func, parameters) func parameters;
 #define COEX_DHCP
 
-/* Set this to 1 to use a seperate interface (p2p0)
- *  for p2p operations.
- */
-#define ENABLE_P2P_INTERFACE	0
-
 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
  * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
  * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165).
@@ -237,7 +234,8 @@
 	struct cfg80211_pmksa *pmksa);
 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
 	struct net_device *dev);
-static void wl_notify_escan_complete(struct wl_priv *wl, struct net_device *ndev, bool aborted);
+static s32 wl_notify_escan_complete(struct wl_priv *wl,
+	struct net_device *ndev, bool aborted, bool fw_abort);
 /*
  * event & event Q handlers for cfg80211 interfaces
  */
@@ -255,6 +253,8 @@
 	const wl_event_msg_t *msg, void *data);
 static void wl_put_event(struct wl_event_q *e);
 static void wl_wakeup_event(struct wl_priv *wl);
+static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
+	const wl_event_msg_t *e, void *data);
 static s32 wl_notify_connect_status(struct wl_priv *wl,
 	struct net_device *ndev,
 	const wl_event_msg_t *e, void *data);
@@ -324,7 +324,7 @@
 static u32 wl_get_ielen(struct wl_priv *wl);
 
 
-static struct wireless_dev *wl_alloc_wdev(struct device *dev);
+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev);
 static void wl_free_wdev(struct wl_priv *wl);
 
 static s32 wl_inform_bss(struct wl_priv *wl);
@@ -547,22 +547,7 @@
 	.channels = __wl_2ghz_channels,
 	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
 	.bitrates = wl_g_rates,
-	.n_bitrates = wl_g_rates_size,
-#if ENABLE_P2P_INTERFACE
-	/* wpa_supplicant sets wmm_enabled based on whether ht_cap
-	 * is present or not. The wmm_enabled is inturn used to
-	 * set the replay counters in the RSN IE. Without this
-	 * the 4way handshake will fail complaining that IE in beacon
-	 * doesn't match with the IE present in the 3/4 EAPOL msg.
-	 */
-	.ht_cap = {
-				IEEE80211_HT_CAP_SGI_20 |
-				IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU,
-				.ht_supported = TRUE,
-				.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
-				.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16
-	}
-#endif
+	.n_bitrates = wl_g_rates_size
 };
 
 static struct ieee80211_supported_band __wl_band_5ghz_a = {
@@ -692,6 +677,29 @@
 	return chanspec;
 }
 
+/* given a channel value, do the endian and chanspec version conversion to
+ * a chanspec_t value
+ * Returns INVCHANSPEC on error
+ */
+chanspec_t
+wl_ch_host_to_driver(u16 channel)
+{
+
+	chanspec_t chanspec;
+
+	chanspec = channel & WL_CHANSPEC_CHAN_MASK;
+
+	if (channel <= CH_MAX_2G_CHANNEL)
+		chanspec |= WL_CHANSPEC_BAND_2G;
+	else
+		chanspec |= WL_CHANSPEC_BAND_5G;
+
+	chanspec |= WL_CHANSPEC_BW_20;
+	chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+
+	return wl_chspec_host_to_driver(chanspec);
+}
+
 /* given a chanspec value from the driver, do the endian and chanspec version conversion to
  * a chanspec_t value
  * Returns INVCHANSPEC on error
@@ -857,36 +865,40 @@
 
 static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy)
 {
-	chanspec_t chspec;
-	int err = 0;
-	struct wl_priv *wl = wiphy_priv(wiphy);
-	struct net_device *dev = wl_to_prmry_ndev(wl);
-	struct ether_addr bssid;
-	struct wl_bss_info *bss = NULL;
-
-	if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
-		/* STA interface is not associated. So start the new interface on a temp
-		 * channel . Later proper channel will be applied by the above framework
-		 * via set_channel (cfg80211 API).
-		 */
-		WL_DBG(("Not associated. Return a temp channel. \n"));
-		return wf_chspec_aton(WL_P2P_TEMP_CHAN);
-	}
-
-
-	*(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
-	if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf,
-		sizeof(WL_EXTRA_BUF_MAX), false))) {
-			WL_ERR(("Failed to get associated bss info, use temp channel \n"));
-			chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
+	if (vsdb_supported) {
+		return wl_ch_host_to_driver(WL_P2P_TEMP_CHAN);
 	}
 	else {
-			bss = (struct wl_bss_info *) (wl->extra_buf + 4);
-			chspec =  bss->chanspec;
-			WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec));
-	}
+		chanspec_t chspec;
+		int err = 0;
+		struct wl_priv *wl = wiphy_priv(wiphy);
+		struct net_device *dev = wl_to_prmry_ndev(wl);
+		struct ether_addr bssid;
+		struct wl_bss_info *bss = NULL;
 
-	return chspec;
+		if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
+			/* STA interface is not associated. So start the new interface on a temp
+			 * channel . Later proper channel will be applied by the above framework
+			 * via set_channel (cfg80211 API).
+			 */
+			WL_DBG(("Not associated. Return a temp channel. \n"));
+			return wl_ch_host_to_driver(WL_P2P_TEMP_CHAN);
+		}
+
+
+		*(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
+		if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf,
+			sizeof(WL_EXTRA_BUF_MAX), false))) {
+				WL_ERR(("Failed to get associated bss info, use temp channel \n"));
+				chspec = wl_ch_host_to_driver(WL_P2P_TEMP_CHAN);
+		}
+		else {
+				bss = (struct wl_bss_info *) (wl->extra_buf + 4);
+				chspec =  bss->chanspec;
+				WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec));
+		}
+		return chspec;
+	}
 }
 
 static struct net_device* wl_cfg80211_add_monitor_if(char *name)
@@ -914,7 +926,7 @@
 	int (*net_attach)(void *dhdp, int ifidx);
 	bool rollback_lock = false;
 
-	/* Use primary I/F for to send commands down */
+	/* Use primary I/F for sending cmds down to firmware */
 	_ndev = wl_to_prmry_ndev(wl);
 
 	WL_DBG(("if name: %s, type: %d\n", name, type));
@@ -978,7 +990,7 @@
 				return ERR_PTR(-EAGAIN);
 			}
 		}
-		if (!p2p_is_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
+		if (wl->p2p && !wl->p2p->on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
 			p2p_on(wl) = true;
 			wl_cfgp2p_set_firm_p2p(wl);
 			wl_cfgp2p_init_discovery(wl);
@@ -991,6 +1003,8 @@
 		strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
 
 
+		wl_notify_escan_complete(wl, _ndev, true, true);
+
 		/* In concurrency case, STA may be already associated in a particular channel.
 		 * so retrieve the current channel of primary interface and then start the virtual
 		 * interface on that.
@@ -1021,7 +1035,7 @@
 			}
 			vwdev->wiphy = wl->wdev->wiphy;
 			WL_INFO((" virtual interface(%s) is created memalloc done \n",
-			wl->p2p->vir_ifname));
+				wl->p2p->vir_ifname));
 			vwdev->iftype = type;
 			_ndev =  wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
 			_ndev->ieee80211_ptr = vwdev;
@@ -1071,8 +1085,8 @@
 	WL_DBG(("Enter\n"));
 
 	if (wl->p2p_net == dev) {
-		/* Since there is no ifidx corresponding to p2p0,
-		 * all commands should be routed through primary I/F
+		/* Since there is no ifidx corresponding to p2p0, cmds to
+		 * firmware should be routed through primary I/F
 		 */
 		dev = wl_to_prmry_ndev(wl);
 	}
@@ -1081,12 +1095,11 @@
 		memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
 		if (wl->p2p->vif_created) {
 			if (wl_get_drv_status(wl, SCANNING, dev)) {
-				wl_cfg80211_scan_abort(wl, dev);
+				wl_notify_escan_complete(wl, dev, true, true);
 			}
 			wldev_iovar_setint(dev, "mpc", 1);
 			wl_set_p2p_status(wl, IF_DELETING);
 			ret = wl_cfgp2p_ifdel(wl, &p2p_mac);
-#if defined(DONGLEHOST)
 			/* Firmware could not delete the interface so we will not get WLC_E_IF
 			* event for cleaning the dhd virtual nw interace
 			* So lets do it here. Failures from fw will ensure the application to do
@@ -1100,7 +1113,6 @@
 					"HANG Notification sent to %s\n", ret, ndev->name));
 				wl_cfg80211_hang(ndev, WLAN_REASON_UNSPECIFIED);
 			}
-#endif /* defined(DONGLEHOST) */
 
 			/* Wait for any pending scan req to get aborted from the sysioc context */
 			timeout = wait_event_interruptible_timeout(wl->netif_change_event,
@@ -1162,6 +1174,8 @@
 			WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
 			p2p_on(wl)));
 			wldev_iovar_setint(ndev, "mpc", 0);
+			wl_notify_escan_complete(wl, ndev, true, true);
+
 			/* In concurrency case, STA may be already associated in a particular
 			 * channel. so retrieve the current channel of primary interface and
 			 * then start the virtual interface on that.
@@ -1199,16 +1213,18 @@
 }
 
 s32
-wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, void* _net_attach)
+wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
+	void* _net_attach)
 {
 	struct wl_priv *wl = wlcfg_drv_priv;
 	s32 ret = BCME_OK;
+	WL_DBG(("Enter"));
 	if (!ndev) {
 		WL_ERR(("net is NULL\n"));
 		return 0;
 	}
 	if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) {
-		WL_DBG(("IF_ADD event received, old interface name: %s,"
+		WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
 			"new name: %s\n", ndev->name, wl->p2p->vir_ifname));
 		/* Assign the net device to CONNECT BSSCFG */
 		strncpy(ndev->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
@@ -1247,11 +1263,11 @@
 				rollback_lock = true;
 			}
 			WL_DBG(("ESCAN COMPLETED\n"));
-			wl_notify_escan_complete(wl, ndev, true);
+			wl_notify_escan_complete(wl, ndev, true, false);
 			if (rollback_lock)
 				rtnl_unlock();
 		}
-		WL_ERR(("IF_DEL event received, net %x, vif name: %s\n",
+		WL_ERR(("IF_DEL event called from dongle, net %x, vif name: %s\n",
 			(unsigned int)ndev, wl->p2p->vir_ifname));
 
 		memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
@@ -1305,8 +1321,8 @@
 
 static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request)
 {
-	u32 n_ssids = request->n_ssids;
-	u32 n_channels = request->n_channels;
+	u32 n_ssids;
+	u32 n_channels;
 	u16 channel;
 	chanspec_t chanspec;
 	s32 i, offset;
@@ -1335,6 +1351,13 @@
 	params->passive_time = htod32(params->passive_time);
 	params->home_time = htod32(params->home_time);
 
+	/* if request is null just exit so it will be all channel broadcast scan */
+	if (!request)
+		return;
+
+	n_ssids = request->n_ssids;
+	n_channels = request->n_channels;
+
 	/* Copy channel array if applicable */
 	WL_SCAN(("### List of channelspecs to scan ###\n"));
 	if (n_channels > 0) {
@@ -1361,8 +1384,8 @@
 			params->channel_list[i] &= WL_CHANSPEC_CHAN_MASK;
 			params->channel_list[i] |= chanspec;
 			WL_SCAN(("Chan : %d, Channel spec: %x \n",
-			channel, params->channel_list[i]));
-			params->channel_list[i] = htod16(params->channel_list[i]);
+				channel, params->channel_list[i]));
+			params->channel_list[i] = wl_chspec_host_to_driver(params->channel_list[i]);
 		}
 	} else {
 		WL_SCAN(("Scanning all channels\n"));
@@ -1544,6 +1567,7 @@
 		params->sync_id = htod16(0x1234);
 		if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) {
 			WL_ERR(("ioctl buffer length not sufficient\n"));
+			kfree(params);
 			err = -ENOMEM;
 			goto exit;
 		}
@@ -1898,6 +1922,7 @@
 	s32 err = 0;
 
 	CHECK_SYS_UP(wl);
+	WL_DBG(("Enter\n"));
 	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
 		(wl->conf->rts_threshold != wiphy->rts_threshold)) {
 		wl->conf->rts_threshold = wiphy->rts_threshold;
@@ -2395,7 +2420,7 @@
 	 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
 	 */
 	if (wl->scan_request) {
-		wl_cfg80211_scan_abort(wl, dev);
+		wl_notify_escan_complete(wl, dev, true, true);
 	}
 	/* Clean BSSID */
 	bzero(&bssid, sizeof(bssid));
@@ -2636,7 +2661,7 @@
 		* Cancel ongoing scan to sync up with sme state machine of cfg80211.
 		*/
 		if (wl->scan_request) {
-			wl_cfg80211_scan_abort(wl, dev);
+			wl_notify_escan_complete(wl, dev, true, true);
 		}
 		wl_set_drv_status(wl, DISCONNECTING, dev);
 		scbval.val = reason_code;
@@ -3105,7 +3130,7 @@
 	} else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
 		u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
 		if (!wl_get_drv_status(wl, CONNECTED, dev) ||
-		    (dhd_is_associated(dhd, NULL) == FALSE)) {
+			(dhd_is_associated(dhd, NULL) == FALSE)) {
 			WL_ERR(("NOT assoc\n"));
 			err = -ENODEV;
 			goto get_station_err;
@@ -3426,49 +3451,19 @@
 	params->active_time = htod32(-1);
 	params->passive_time = htod32(-1);
 	params->home_time = htod32(10);
-	params->channel_list[0] = wl_chspec_host_to_driver(channel);
+	if (channel == -1)
+		params->channel_list[0] = htodchanspec(channel);
+	else
+		params->channel_list[0] = wl_ch_host_to_driver(channel);
 
 	/* Our scan params have 1 channel and 0 ssids */
 	params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
-	(num_chans & WL_SCAN_PARAMS_COUNT_MASK));
+		(num_chans & WL_SCAN_PARAMS_COUNT_MASK));
 
 	*out_params_size = params_size;	/* rtn size to the caller */
 	return params;
 }
-s32
-wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
-{
-	wl_scan_params_t *params = NULL;
-	s32 params_size = 0;
-	s32 err = BCME_OK;
-	unsigned long flags;
 
-	WL_DBG(("Enter\n"));
-
-	/* Our scan params only need space for 1 channel and 0 ssids */
-	params = wl_cfg80211_scan_alloc_params(-1, 0, &params_size);
-	if (params == NULL) {
-		WL_ERR(("scan params allocation failed \n"));
-		err = -ENOMEM;
-	} else {
-		/* Do a scan abort to stop the driver's scan engine */
-		err = wldev_ioctl(ndev, WLC_SCAN, params, params_size, true);
-		if (err < 0) {
-			WL_ERR(("scan abort  failed \n"));
-		}
-	}
-	del_timer_sync(&wl->scan_timeout);
-	spin_lock_irqsave(&wl->cfgdrv_lock, flags);
-	if (wl->scan_request) {
-		cfg80211_scan_done(wl->scan_request, true);
-		wl->scan_request = NULL;
-	}
-	wl_clr_drv_status(wl, SCANNING, ndev);
-	spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
-	if (params)
-		kfree(params);
-	return err;
-}
 static s32
 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
 	struct ieee80211_channel * channel,
@@ -3491,7 +3486,7 @@
 	}
 
 	if (wl_get_drv_status(wl, SCANNING, ndev)) {
-		wl_cfg80211_scan_abort(wl, ndev);
+		wl_notify_escan_complete(wl, ndev, true, true);
 	}
 
 	target_channel = ieee80211_frequency_to_channel(channel->center_freq);
@@ -3503,7 +3498,7 @@
 	*cookie = id;
 	cfg80211_ready_on_channel(dev, *cookie, channel,
 		channel_type, duration, GFP_KERNEL);
-	if (!p2p_is_on(wl)) {
+	if (wl->p2p && !wl->p2p->on) {
 		get_primary_mac(wl, &primary_mac);
 		wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
 
@@ -3555,7 +3550,7 @@
 		 */
 		wl_clr_drv_status(wl, SENDING_ACT_FRM, wl->afx_hdl->dev);
 		wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
-		wl_cfg80211_scan_abort(wl, dev);
+		wl_notify_escan_complete(wl, dev, true, true);
 		wl_cfgp2p_discover_enable_search(wl, false);
 		tx_act_frm->channel = wl->afx_hdl->peer_chan;
 		wl->afx_hdl->ack_recv = (wl_cfgp2p_tx_action_frame(wl, dev,
@@ -3566,7 +3561,6 @@
 static void
 wl_cfg80211_afx_handler(struct work_struct *work)
 {
-
 	struct afx_hdl *afx_instance;
 	struct wl_priv *wl = wlcfg_drv_priv;
 	afx_instance = container_of(work, struct afx_hdl, work);
@@ -3733,7 +3727,7 @@
 			* tx is still in progress (including the dwell time),
 			* then this new action frame will not be sent out.
 			*/
-			wl_cfg80211_scan_abort(wl, dev);
+			wl_notify_escan_complete(wl, dev, true, true);
 
 		}
 
@@ -3768,6 +3762,7 @@
 		ieee80211_frequency_to_channel(channel->center_freq);
 
 	if (channel->band == IEEE80211_BAND_5GHZ) {
+		WL_DBG(("5GHz channel %d", af_params->channel));
 		err = wldev_ioctl(dev, WLC_SET_CHANNEL,
 			&af_params->channel, sizeof(af_params->channel), true);
 		if (err < 0) {
@@ -3927,6 +3922,33 @@
 }
 
 static s32
+wl_validate_opensecurity(struct net_device *dev, s32 bssidx)
+{
+	s32 err = BCME_OK;
+
+	/* set auth */
+	err = wldev_iovar_setint_bsscfg(dev, "auth", 0, bssidx);
+	if (err < 0) {
+		WL_ERR(("auth error %d\n", err));
+		return BCME_ERROR;
+	}
+	/* set wsec */
+	err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx);
+	if (err < 0) {
+		WL_ERR(("wsec error %d\n", err));
+		return BCME_ERROR;
+	}
+	/* set upper-layer auth */
+	err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", WPA_AUTH_NONE, bssidx);
+	if (err < 0) {
+		WL_ERR(("wpa_auth error %d\n", err));
+		return BCME_ERROR;
+	}
+
+	return 0;
+}
+
+static s32
 wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
 {
 	s32 len = 0;
@@ -4373,8 +4395,10 @@
 						wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
 						GFP_KERNEL);
 				}
-			} else
+			} else {
+				wl_validate_opensecurity(dev, bssidx);
 				wl->ap_info->security_mode = false;
+			}
 			/* find the WPSIE */
 			if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail,
 				info->tail_len)) != NULL) {
@@ -4585,23 +4609,17 @@
 	return err;
 }
 
-static struct wireless_dev *wl_alloc_wdev(struct device *dev)
+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev)
 {
-	struct wireless_dev *wdev;
 	s32 err = 0;
-	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
-	if (unlikely(!wdev)) {
-		WL_ERR(("Could not allocate wireless device\n"));
-		return ERR_PTR(-ENOMEM);
-	}
 	wdev->wiphy =
 	    wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv));
 	if (unlikely(!wdev->wiphy)) {
 		WL_ERR(("Couldn not allocate wiphy device\n"));
 		err = -ENOMEM;
-		goto wiphy_new_out;
+		return err;
 	}
-	set_wiphy_dev(wdev->wiphy, dev);
+	set_wiphy_dev(wdev->wiphy, sdiofunc_dev);
 	wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
 	/* Report  how many SSIDs Driver can support per Scan request */
 	wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX;
@@ -4611,7 +4629,7 @@
 		| BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
 
 	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
-	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
+
 	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 	wdev->wiphy->cipher_suites = __wl_cipher_suites;
 	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
@@ -4628,7 +4646,9 @@
 		WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS |
 #endif
 		WIPHY_FLAG_4ADDR_STATION;
-
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+	wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
+#endif
 	WL_DBG(("Registering custom regulatory)\n"));
 	wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 	wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
@@ -4636,17 +4656,9 @@
 	err = wiphy_register(wdev->wiphy);
 	if (unlikely(err < 0)) {
 		WL_ERR(("Couldn not register wiphy device (%d)\n", err));
-		goto wiphy_register_out;
+		wiphy_free(wdev->wiphy);
 	}
-	return wdev;
-
-wiphy_register_out:
-	wiphy_free(wdev->wiphy);
-
-wiphy_new_out:
-	kfree(wdev);
-
-	return ERR_PTR(err);
+	return err;
 }
 
 static void wl_free_wdev(struct wl_priv *wl)
@@ -4713,7 +4725,7 @@
 	}
 	mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
 	notif_bss_info->channel =
-		bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
+		bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(wl_chspec_driver_to_host(bi->chanspec));
 
 	if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
@@ -4754,11 +4766,14 @@
 			notif_bss_info->frame_len));
 
 	signal = notif_bss_info->rssi * 100;
-#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
 	if (wl->p2p_net && wl->scan_request &&
-		wl->scan_request->dev == wl->p2p_net) {
+		((wl->scan_request->dev == wl->p2p_net) ||
+		(wl->scan_request->dev == wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)))) {
 #else
-	if (p2p_is_on(wl) && p2p_scan(wl)) {
+	if (p2p_is_on(wl) && (p2p_scan(wl) ||
+		(wl->scan_request->dev == wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)))) {
 #endif
 		/* find the P2PIE, if we do not find it, we will discard this frame */
 		wifi_p2p_ie_t * p2p_ie;
@@ -4790,7 +4805,7 @@
 	u32 status =  ntoh32(e->status);
 	u16 flags = ntoh16(e->flags);
 
-	WL_DBG(("event %d, status %d\n", event, status));
+	WL_DBG(("event %d, status %d flags %x\n", event, status, flags));
 	if (event == WLC_E_SET_SSID) {
 		if (status == WLC_E_STATUS_SUCCESS) {
 			if (!wl_is_ibssmode(wl, ndev))
@@ -4836,94 +4851,144 @@
 	return false;
 }
 
+/* The mainline kernel >= 3.2.0 has support for indicating new/del station
+ * to AP/P2P GO via events. If this change is backported to kernel for which
+ * this driver is being built, then define WL_CFG80211_STA_EVENT. You
+ * should use this new/del sta event mechanism for BRCM supplicant >= 22.
+ */
 static s32
-wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
+wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
 	const wl_event_msg_t *e, void *data)
 {
-	bool act;
-	bool isfree = false;
 	s32 err = 0;
-	s32 freq;
-	s32 channel;
-	u8 body[200];
 	u32 event = ntoh32(e->event_type);
 	u32 reason = ntoh32(e->reason);
 	u32 len = ntoh32(e->datalen);
 
-	u16 fc = 0;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT)
+	bool isfree = false;
 	u8 *mgmt_frame;
 	u8 bsscfgidx = e->bsscfgidx;
+	s32 freq;
+	s32 channel;
+	u8 body[WL_FRAME_LEN];
+	u16 fc = 0;
+
 	struct ieee80211_supported_band *band;
 	struct ether_addr da;
 	struct ether_addr bssid;
 	struct wiphy *wiphy = wl_to_wiphy(wl);
 	channel_info_t ci;
+#else
+	struct station_info sinfo;
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !WL_CFG80211_STA_EVENT */
 
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT)
 	memset(body, 0, sizeof(body));
 	memset(&bssid, 0, ETHER_ADDR_LEN);
-	WL_DBG(("Enter \n"));
+	WL_DBG(("Enter event %d ndev %p\n", event, ndev));
 	if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID)
 		return WL_INVALID;
 
-	if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
-		memcpy(body, data, len);
-		wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
-			NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
-		memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
-		err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
-		switch (event) {
-			case WLC_E_ASSOC_IND:
-				fc = FC_ASSOC_REQ;
-				break;
-			case WLC_E_REASSOC_IND:
-				fc = FC_REASSOC_REQ;
-				break;
-			case WLC_E_DISASSOC_IND:
-				fc = FC_DISASSOC;
-				break;
-			case WLC_E_DEAUTH_IND:
-				fc = FC_DISASSOC;
-				break;
-			case WLC_E_DEAUTH:
-				fc = FC_DISASSOC;
-				break;
-			default:
-				fc = 0;
-				goto exit;
-		}
-		if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
-			return err;
+	if (len > WL_FRAME_LEN) {
+		WL_ERR(("Received frame length %d from dongle is greater than"
+			" allocated body buffer len %d", len, WL_FRAME_LEN));
+		goto exit;
+	}
+	memcpy(body, data, len);
+	wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
+		NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
+	memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
+	err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+	switch (event) {
+		case WLC_E_ASSOC_IND:
+			fc = FC_ASSOC_REQ;
+			break;
+		case WLC_E_REASSOC_IND:
+			fc = FC_REASSOC_REQ;
+			break;
+		case WLC_E_DISASSOC_IND:
+			fc = FC_DISASSOC;
+			break;
+		case WLC_E_DEAUTH_IND:
+			fc = FC_DISASSOC;
+			break;
+		case WLC_E_DEAUTH:
+			fc = FC_DISASSOC;
+			break;
+		default:
+			fc = 0;
+			goto exit;
+	}
+	if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
+		return err;
 
-		channel = dtoh32(ci.hw_channel);
-		if (channel <= CH_MAX_2G_CHANNEL)
-			band = wiphy->bands[IEEE80211_BAND_2GHZ];
-		else
-			band = wiphy->bands[IEEE80211_BAND_5GHZ];
+	channel = dtoh32(ci.hw_channel);
+	if (channel <= CH_MAX_2G_CHANNEL)
+		band = wiphy->bands[IEEE80211_BAND_2GHZ];
+	else
+		band = wiphy->bands[IEEE80211_BAND_5GHZ];
 
 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
-		freq = ieee80211_channel_to_frequency(channel);
-		(void)band->band;
+	freq = ieee80211_channel_to_frequency(channel);
+	(void)band->band;
 #else
-		freq = ieee80211_channel_to_frequency(channel, band->band);
+	freq = ieee80211_channel_to_frequency(channel, band->band);
 #endif
 
-		err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
+	err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
 		&mgmt_frame, &len, body);
-		if (err < 0)
-				goto exit;
-		isfree = true;
+	if (err < 0)
+		goto exit;
+	isfree = true;
 
-		if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
-			cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
-		} else if (event == WLC_E_DISASSOC_IND) {
-			cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
-		} else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
-			cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
+	if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
+		cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
+	} else if (event == WLC_E_DISASSOC_IND) {
+		cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
+	} else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+		cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
+	}
+
+exit:
+	if (isfree)
+		kfree(mgmt_frame);
+	return err;
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */
+	sinfo.filled = 0;
+	if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) &&
+		reason == DOT11_SC_SUCCESS) {
+		sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
+		if (!data) {
+			WL_ERR(("No IEs present in ASSOC/REASSOC_IND"));
+			return -EINVAL;
 		}
+		sinfo.assoc_req_ies = data;
+		sinfo.assoc_req_ies_len = len;
+		cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC);
+	} else if (event == WLC_E_DISASSOC_IND) {
+		cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
+	} else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+		cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
+	}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */
+	return err;
+}
 
+static s32
+wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
+	const wl_event_msg_t *e, void *data)
+{
+	bool act;
+	s32 err = 0;
+	u32 event = ntoh32(e->event_type);
+
+	if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
+		wl_notify_connect_status_ap(wl, ndev, e, data);
 	} else {
-		WL_DBG(("wl_notify_connect_status : event %d status : %d \n",
-		ntoh32(e->event_type), ntoh32(e->status)));
+		WL_DBG(("wl_notify_connect_status : event %d status : %d ndev %p\n",
+			ntoh32(e->event_type), ntoh32(e->status), ndev));
 		if (wl_is_linkup(wl, e, ndev)) {
 			wl_link_up(wl);
 			act = true;
@@ -4946,30 +5011,34 @@
 
 		} else if (wl_is_linkdown(wl, e)) {
 			if (wl->scan_request) {
-				del_timer_sync(&wl->scan_timeout);
 				if (wl->escan_on) {
-					wl_notify_escan_complete(wl, ndev, true);
-				} else
+					wl_notify_escan_complete(wl, ndev, true, true);
+				} else {
+					del_timer_sync(&wl->scan_timeout);
 					wl_iscan_aborted(wl);
+				}
 			}
 			if (wl_get_drv_status(wl, CONNECTED, ndev)) {
 				scb_val_t scbval;
 				u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
 				printk("link down, call cfg80211_disconnected\n");
 				wl_clr_drv_status(wl, CONNECTED, ndev);
-				/* To make sure disconnect, explictly send dissassoc
-				*  for BSSID 00:00:00:00:00:00 issue
-				*/
-				scbval.val = WLAN_REASON_DEAUTH_LEAVING;
+				if (! wl_get_drv_status(wl, DISCONNECTING, ndev)) {
+					/* To make sure disconnect, explictly send dissassoc
+					*  for BSSID 00:00:00:00:00:00 issue
+					*/
+					scbval.val = WLAN_REASON_DEAUTH_LEAVING;
 
-				memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
-				scbval.val = htod32(scbval.val);
-				wldev_ioctl(ndev, WLC_DISASSOC, &scbval,
-					sizeof(scb_val_t), true);
-				cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
-				wl_link_down(wl);
-				wl_init_prof(wl, ndev);
-			} else if (wl_get_drv_status(wl, CONNECTING, ndev)) {
+					memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
+					scbval.val = htod32(scbval.val);
+					wldev_ioctl(ndev, WLC_DISASSOC, &scbval,
+						sizeof(scb_val_t), true);
+					cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
+					wl_link_down(wl);
+					wl_init_prof(wl, ndev);
+				}
+			}
+			else if (wl_get_drv_status(wl, CONNECTING, ndev)) {
 				printk("link down, during connecting\n");
 				wl_bss_connect_done(wl, ndev, e, data, false);
 			}
@@ -4980,11 +5049,12 @@
 				event, (int)ntoh32(e->status));
 			/* Clean up any pending scan request */
 			if (wl->scan_request) {
-				del_timer_sync(&wl->scan_timeout);
 				if (wl->escan_on) {
-					wl_notify_escan_complete(wl, ndev, true);
-				} else
+					wl_notify_escan_complete(wl, ndev, true, true);
+				} else {
+					del_timer_sync(&wl->scan_timeout);
 					wl_iscan_aborted(wl);
+				}
 			}
 			if (wl_get_drv_status(wl, CONNECTING, ndev))
 				wl_bss_connect_done(wl, ndev, e, data, false);
@@ -4992,9 +5062,6 @@
 			printk("%s nothing\n", __FUNCTION__);
 		}
 	}
-exit:
-	if (isfree)
-		kfree(mgmt_frame);
 	return err;
 }
 
@@ -5240,7 +5307,7 @@
 
 	WL_DBG((" enter\n"));
 	if (wl->scan_request) {
-		wl_cfg80211_scan_abort(wl, ndev);
+		wl_notify_escan_complete(wl, ndev, true, true);
 	}
 	if (wl_get_drv_status(wl, CONNECTING, ndev)) {
 		wl_clr_drv_status(wl, CONNECTING, ndev);
@@ -5467,7 +5534,7 @@
 		 * After complete GO Negotiation, roll back to mpc mode
 		 */
 		if (act_frm && ((act_frm->subtype == P2P_PAF_GON_CONF) ||
-		(act_frm->subtype == P2P_PAF_PROVDIS_RSP))) {
+			(act_frm->subtype == P2P_PAF_PROVDIS_RSP))) {
 			wldev_iovar_setint(dev, "mpc", 1);
 		}
 	} else {
@@ -5827,7 +5894,7 @@
 	if (wl->scan_request) {
 		WL_ERR(("timer expired\n"));
 		if (wl->escan_on)
-			wl_notify_escan_complete(wl, wl->escan_info.ndev, true);
+			wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true);
 		else
 			wl_notify_iscan_complete(wl_to_iscan(wl), true);
 	}
@@ -5882,36 +5949,85 @@
 	struct wl_priv *wl = wlcfg_drv_priv;
 
 	WL_DBG(("Enter \n"));
-	if (!wdev || dev == wl_to_prmry_ndev(wl))
+	if (!wdev || !wl || dev == wl_to_prmry_ndev(wl))
 		return NOTIFY_DONE;
 	switch (state) {
 		case NETDEV_UNREGISTER:
-				/* after calling list_del_rcu(&wdev->list) */
-				wl_dealloc_netinfo(wl, ndev);
-				break;
+			/* after calling list_del_rcu(&wdev->list) */
+			wl_dealloc_netinfo(wl, ndev);
+			break;
+		case NETDEV_GOING_DOWN:
+			/* At NETDEV_DOWN state, wdev_cleanup_work work will be called.
+			*  In front of door, the function checks
+			*  whether current scan is working or not.
+			*  If the scanning is still working, wdev_cleanup_work call WARN_ON and
+			*  make the scan done forcibly.
+			*/
+			if (wl_get_drv_status(wl, SCANNING, dev)) {
+				if (wl->escan_on) {
+					wl_notify_escan_complete(wl, dev, true, true);
+				}
+			}
+			break;
 	}
 	return NOTIFY_DONE;
 }
 static struct notifier_block wl_cfg80211_netdev_notifier = {
 	.notifier_call = wl_cfg80211_netdev_notifier_call,
 };
-static void wl_notify_escan_complete(struct wl_priv *wl,
+
+static s32 wl_notify_escan_complete(struct wl_priv *wl,
 	struct net_device *ndev,
-	bool aborted)
+	bool aborted, bool fw_abort)
 {
+	wl_scan_params_t *params = NULL;
+	s32 params_size = 0;
+	s32 err = BCME_OK;
 	unsigned long flags;
+	struct net_device *dev;
 
 	WL_DBG(("Enter \n"));
-	wl_clr_drv_status(wl, SCANNING, ndev);
-	if (p2p_is_on(wl))
-		wl_clr_p2p_status(wl, SCANNING);
 
+	if (wl->scan_request) {
+		if (wl->scan_request->dev == wl->p2p_net)
+			dev = wl_to_prmry_ndev(wl);
+		else
+			dev = wl->scan_request->dev;
+	}
+	else {
+		WL_ERR(("wl->scan_request is NULL may be internal scan."
+			"doing scan_abort for ndev %p primary %p p2p_net %p",
+				ndev, wl_to_prmry_ndev(wl), wl->p2p_net));
+		dev = ndev;
+	}
+	if (fw_abort) {
+		/* Our scan params only need space for 1 channel and 0 ssids */
+		params = wl_cfg80211_scan_alloc_params(-1, 0, &params_size);
+		if (params == NULL) {
+			WL_ERR(("scan params allocation failed \n"));
+			err = -ENOMEM;
+		} else {
+			/* Do a scan abort to stop the driver's scan engine */
+			err = wldev_ioctl(dev, WLC_SCAN, params, params_size, true);
+			if (err < 0) {
+				WL_ERR(("scan abort  failed \n"));
+			}
+		}
+	}
+	del_timer_sync(&wl->scan_timeout);
 	spin_lock_irqsave(&wl->cfgdrv_lock, flags);
 	if (likely(wl->scan_request)) {
 		cfg80211_scan_done(wl->scan_request, aborted);
 		wl->scan_request = NULL;
 	}
+	if (p2p_is_on(wl))
+		wl_clr_p2p_status(wl, SCANNING);
+	wl_clr_drv_status(wl, SCANNING, dev);
 	spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+	if (params)
+		kfree(params);
+
+	return err;
 }
 
 static s32 wl_escan_handler(struct wl_priv *wl,
@@ -5999,7 +6115,8 @@
 					: list->bss_info;
 
 				if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
-					CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
+					(CHSPEC_BAND(wl_chspec_driver_to_host(bi->chanspec))
+					== CHSPEC_BAND(wl_chspec_driver_to_host(bss->chanspec))) &&
 					bi->SSID_len == bss->SSID_len &&
 					!bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
 					if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
@@ -6038,11 +6155,10 @@
 				complete(&wl->act_frm_scan);
 		} else if (likely(wl->scan_request)) {
 			mutex_lock(&wl->usr_sync);
-			del_timer_sync(&wl->scan_timeout);
 			WL_INFO(("ESCAN COMPLETED\n"));
 			wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
 			wl_inform_bss(wl);
-			wl_notify_escan_complete(wl, ndev, false);
+			wl_notify_escan_complete(wl, ndev, false, false);
 			mutex_unlock(&wl->usr_sync);
 		}
 	}
@@ -6056,11 +6172,10 @@
 				complete(&wl->act_frm_scan);
 		} else if (likely(wl->scan_request)) {
 			mutex_lock(&wl->usr_sync);
-			del_timer_sync(&wl->scan_timeout);
 			WL_INFO(("ESCAN ABORTED\n"));
 			wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
 			wl_inform_bss(wl);
-			wl_notify_escan_complete(wl, ndev, true);
+			wl_notify_escan_complete(wl, ndev, true, false);
 			mutex_unlock(&wl->usr_sync);
 		}
 	}
@@ -6075,10 +6190,9 @@
 				complete(&wl->act_frm_scan);
 		} else if (likely(wl->scan_request)) {
 			mutex_lock(&wl->usr_sync);
-			del_timer_sync(&wl->scan_timeout);
 			wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
 			wl_inform_bss(wl);
-			wl_notify_escan_complete(wl, ndev, true);
+			wl_notify_escan_complete(wl, ndev, true, false);
 			mutex_unlock(&wl->usr_sync);
 		}
 	}
@@ -6167,7 +6281,7 @@
 	unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier);
 }
 
-#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
 static s32 wl_cfg80211_attach_p2p(void)
 {
 	struct wl_priv *wl = wlcfg_drv_priv;
@@ -6202,7 +6316,7 @@
 
 	return 0;
 }
-#endif /* defined(WLP2P) && (ENABLE_P2P_INTERFACE) */
+#endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */
 
 s32 wl_cfg80211_attach_post(struct net_device *ndev)
 {
@@ -6217,13 +6331,15 @@
 	if (wl && !wl_get_drv_status(wl, READY, ndev)) {
 			if (wl->wdev &&
 				wl_cfgp2p_supported(wl, ndev)) {
+#if !defined(WL_ENABLE_P2P_IF)
 				wl->wdev->wiphy->interface_modes |=
 					(BIT(NL80211_IFTYPE_P2P_CLIENT)|
 					BIT(NL80211_IFTYPE_P2P_GO));
+#endif
 				if ((err = wl_cfgp2p_init_priv(wl)) != 0)
 					goto fail;
 
-#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
 				if (wl->p2p_net) {
 					/* Update MAC addr for p2p0 interface here. */
 					memcpy(wl->p2p_net->dev_addr, ndev->dev_addr, ETH_ALEN);
@@ -6235,7 +6351,7 @@
 					" Couldn't update the MAC Address for p2p0 \n"));
 					return -ENODEV;
 				}
-#endif /* defined(WLP2P) && (ENABLE_P2P_INTERFACE) */
+#endif /* defined(WLP2P) && (WL_ENABLE_P2P_IF) */
 
 				wl->p2p_supported = true;
 			}
@@ -6260,10 +6376,17 @@
 	}
 	WL_DBG(("func %p\n", wl_cfg80211_get_parent_dev()));
 	dev = wl_cfg80211_get_parent_dev();
-	wdev = wl_alloc_wdev(dev);
-	if (IS_ERR(wdev))
-		return -ENOMEM;
 
+	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+	if (unlikely(!wdev)) {
+		WL_ERR(("Could not allocate wireless device\n"));
+		return -ENOMEM;
+	}
+	err = wl_setup_wiphy(wdev, dev);
+	if (unlikely(err)) {
+		kfree(wdev);
+		return -ENOMEM;
+	}
 	wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
 	wl = (struct wl_priv *)wiphy_priv(wdev->wiphy);
 	wl->wdev = wdev;
@@ -6300,7 +6423,7 @@
 
 	wlcfg_drv_priv = wl;
 
-#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
 	err = wl_cfg80211_attach_p2p();
 	if (err)
 		goto cfg80211_attach_out;
@@ -6327,7 +6450,7 @@
 	wl_cfg80211_btcoex_deinit(wl);
 #endif 
 
-#if defined(WLP2P) && ENABLE_P2P_INTERFACE
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
 	wl_cfg80211_detach_p2p();
 #endif
 	wl_setup_rfkill(wl, FALSE);
@@ -6423,7 +6546,7 @@
 		}
 		DHD_OS_WAKE_UNLOCK(wl->pub);
 	}
-	WL_DBG(("%s was terminated\n", __func__));
+	WL_ERR(("%s was terminated\n", __func__));
 	complete_and_exit(&tsk->completed, 0);
 	return 0;
 }
@@ -6440,10 +6563,12 @@
 	WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
 #endif /* (WL_DBG_LEVEL > 0) */
 
-	if (event_type == WLC_E_PFN_NET_FOUND)
-		WL_ERR((" PNOEVENT: PNO_NET_FOUND\n"));
-	else if (event_type == WLC_E_PFN_NET_LOST)
-		WL_ERR((" PNOEVENT: PNO_NET_LOST\n"));
+	if (event_type == WLC_E_PFN_NET_FOUND) {
+		WL_DBG((" PNOEVENT: PNO_NET_FOUND\n"));
+	}
+	else if (event_type == WLC_E_PFN_NET_LOST) {
+		WL_DBG((" PNOEVENT: PNO_NET_LOST\n"));
+	}
 
 	if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
 		wl_wakeup_event(wl);
@@ -6608,24 +6733,64 @@
 s32 wl_update_wiphybands(struct wl_priv *wl)
 {
 	struct wiphy *wiphy;
-	s8 phylist_buf[128];
-	s8 *phy;
+	u32 bandlist[3];
+	u32 nband = 0;
+	u32 i = 0;
 	s32 err = 0;
+	int nmode = 0;
+	int bw_40 = 0;
+	int index = 0;
 
-	err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_PHYLIST, phylist_buf,
-		sizeof(phylist_buf), false);
+	WL_DBG(("Entry"));
+	memset(bandlist, 0, sizeof(bandlist));
+	err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_BANDLIST, bandlist,
+		sizeof(bandlist), false);
 	if (unlikely(err)) {
 		WL_ERR(("error (%d)\n", err));
 		return err;
 	}
-	phy = phylist_buf;
-	for (; *phy; phy++) {
-		if (*phy == 'a' || *phy == 'n') {
-			wiphy = wl_to_wiphy(wl);
+	wiphy = wl_to_wiphy(wl);
+	nband = bandlist[0];
+	wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
+	wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
+
+	err = wldev_iovar_getint(wl_to_prmry_ndev(wl), "nmode", &nmode);
+	if (unlikely(err)) {
+		WL_ERR(("error (%d)\n", err));
+	}
+
+	err = wldev_iovar_getint(wl_to_prmry_ndev(wl), "mimo_bw_cap", &bw_40);
+	if (unlikely(err)) {
+		WL_ERR(("error (%d)\n", err));
+	}
+
+	for (i = 1; i <= nband && i < sizeof(bandlist); i++) {
+		index = -1;
+		if (bandlist[i] == WLC_BAND_5G) {
 			wiphy->bands[IEEE80211_BAND_5GHZ] =
 				&__wl_band_5ghz_a;
+				index = IEEE80211_BAND_5GHZ;
+		} else if (bandlist[i] == WLC_BAND_2G) {
+			wiphy->bands[IEEE80211_BAND_2GHZ] =
+				&__wl_band_2ghz;
+				index = IEEE80211_BAND_2GHZ;
+		}
+
+		if ((index >= 0) && nmode) {
+			wiphy->bands[index]->ht_cap.cap =
+			IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40
+			| IEEE80211_HT_CAP_MAX_AMSDU;
+			wiphy->bands[index]->ht_cap.ht_supported = TRUE;
+			wiphy->bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+			wiphy->bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+		}
+
+		if ((index >= 0) && bw_40) {
+			wiphy->bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
 		}
 	}
+
+	wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
 	return err;
 }
 
@@ -6635,7 +6800,7 @@
 	struct net_device *ndev = wl_to_prmry_ndev(wl);
 	struct wireless_dev *wdev = ndev->ieee80211_ptr;
 
-	WL_TRACE(("In\n"));
+	WL_DBG(("In\n"));
 
 	err = dhd_config_dongle(wl, false);
 	if (unlikely(err))
@@ -6663,7 +6828,7 @@
 	struct net_info *iter, *next;
 	struct net_device *ndev = wl_to_prmry_ndev(wl);
 
-	WL_TRACE(("In\n"));
+	WL_DBG(("In\n"));
 	/* Check if cfg80211 interface is already down */
 	if (!wl_get_drv_status(wl, READY, ndev))
 		return err;	/* it is even not ready */
@@ -6704,10 +6869,10 @@
 {
 	struct wl_priv *wl;
 	s32 err = 0;
-	int val = 0;
+	int val = 1;
 
 	(void)para;
-	WL_TRACE(("In\n"));
+	WL_DBG(("In\n"));
 	wl = wlcfg_drv_priv;
 
 	if ((err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_VERSION, &val,
@@ -6754,7 +6919,7 @@
 	s32 err = 0;
 
 	(void)para;
-	WL_TRACE(("In\n"));
+	WL_DBG(("In\n"));
 	wl = wlcfg_drv_priv;
 	mutex_lock(&wl->usr_sync);
 	err = __wl_cfg80211_down(wl);
@@ -7117,3 +7282,21 @@
 		0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
 	memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN);
 }
+
+int wl_cfg80211_do_driver_init(struct net_device *net)
+{
+	struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net);
+
+	if (!wl || !wl->wdev)
+		return -EINVAL;
+
+	if (dhd_do_driver_init(wl->wdev->netdev) < 0)
+		return -1;
+
+	return 0;
+}
+
+void wl_cfg80211_enable_trace(int level)
+{
+	wl_dbg_level |= WL_DBG_DBG;
+}
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 6e43c3f..edf8a30 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.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_cfg80211.h 307885 2012-01-12 23:30:48Z $
+ * $Id: wl_cfg80211.h 316895 2012-02-24 00:05:41Z $
  */
 
 #ifndef _wl_cfg80211_h_
@@ -423,7 +423,7 @@
 	bool pwr_save;
 	bool roam_on;		/* on/off switch for self-roaming */
 	bool scan_tried;	/* indicates if first scan attempted */
-	u8 *ioctl_buf;	/* ioctl buffer */
+	u8 *ioctl_buf;		/* ioctl buffer */
 	struct mutex ioctl_buf_sync;
 	u8 *escan_ioctl_buf;
 	u8 *extra_buf;	/* maily to grab assoc information */
@@ -633,7 +633,8 @@
 
 extern s32 wl_cfg80211_up(void *para);
 extern s32 wl_cfg80211_down(void *para);
-extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx, void* _net_attach);
+extern s32 wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
+	void* _net_attach);
 extern s32 wl_cfg80211_ifdel_ops(struct net_device *net);
 extern s32 wl_cfg80211_notify_ifdel(struct net_device *ndev);
 extern s32 wl_cfg80211_is_progress_ifadd(void);
@@ -649,9 +650,9 @@
 extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len);
 extern int wl_cfg80211_hang(struct net_device *dev, u16 reason);
 extern s32 wl_mode_to_nl80211_iftype(s32 mode);
-
-/* do scan abort */
-extern s32 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev);
-
+int wl_cfg80211_do_driver_init(struct net_device *net);
+void wl_cfg80211_enable_trace(int level);
 extern s32 wl_cfg80211_if_is_group_owner(void);
+extern chanspec_t wl_ch_host_to_driver(u16 channel);
+
 #endif				/* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index 96e9029..eb76fd0 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.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_cfgp2p.c 308397 2012-01-15 07:32:58Z $
+ * $Id: wl_cfgp2p.c 321498 2012-03-15 12:54:13Z $
  *
  */
 #include <typedefs.h>
@@ -140,43 +140,43 @@
 		pact_frm = (wifi_p2p_pub_act_frame_t *)frame;
 		switch (pact_frm->subtype) {
 			case P2P_PAF_GON_REQ:
-				CFGP2P_ERR(("%s P2P Group Owner Negotiation Req Frame\n",
+				CFGP2P_DBG(("%s P2P Group Owner Negotiation Req Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_PAF_GON_RSP:
-				CFGP2P_ERR(("%s P2P Group Owner Negotiation Rsp Frame\n",
+				CFGP2P_DBG(("%s P2P Group Owner Negotiation Rsp Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_PAF_GON_CONF:
-				CFGP2P_ERR(("%s P2P Group Owner Negotiation Confirm Frame\n",
+				CFGP2P_DBG(("%s P2P Group Owner Negotiation Confirm Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_PAF_INVITE_REQ:
-				CFGP2P_ERR(("%s P2P Invitation Request  Frame\n",
+				CFGP2P_DBG(("%s P2P Invitation Request  Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_PAF_INVITE_RSP:
-				CFGP2P_ERR(("%s P2P Invitation Response Frame\n",
+				CFGP2P_DBG(("%s P2P Invitation Response Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_PAF_DEVDIS_REQ:
-				CFGP2P_ERR(("%s P2P Device Discoverability Request Frame\n",
+				CFGP2P_DBG(("%s P2P Device Discoverability Request Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_PAF_DEVDIS_RSP:
-				CFGP2P_ERR(("%s P2P Device Discoverability Response Frame\n",
+				CFGP2P_DBG(("%s P2P Device Discoverability Response Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_PAF_PROVDIS_REQ:
-				CFGP2P_ERR(("%s P2P Provision Discovery Request Frame\n",
+				CFGP2P_DBG(("%s P2P Provision Discovery Request Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_PAF_PROVDIS_RSP:
-				CFGP2P_ERR(("%s P2P Provision Discovery Response Frame\n",
+				CFGP2P_DBG(("%s P2P Provision Discovery Response Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			default:
-				CFGP2P_ERR(("%s Unknown P2P Public Action Frame\n",
+				CFGP2P_DBG(("%s Unknown P2P Public Action Frame\n",
 					(tx)? "TX": "RX"));
 
 		}
@@ -185,23 +185,23 @@
 		act_frm = (wifi_p2p_action_frame_t *)frame;
 		switch (act_frm->subtype) {
 			case P2P_AF_NOTICE_OF_ABSENCE:
-				CFGP2P_ERR(("%s P2P Notice of Absence Frame\n",
+				CFGP2P_DBG(("%s P2P Notice of Absence Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_AF_PRESENCE_REQ:
-				CFGP2P_ERR(("%s P2P Presence Request Frame\n",
+				CFGP2P_DBG(("%s P2P Presence Request Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_AF_PRESENCE_RSP:
-				CFGP2P_ERR(("%s P2P Presence Response Frame\n",
+				CFGP2P_DBG(("%s P2P Presence Response Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			case P2P_AF_GO_DISC_REQ:
-				CFGP2P_ERR(("%s P2P Discoverability Request Frame\n",
+				CFGP2P_DBG(("%s P2P Discoverability Request Frame\n",
 					(tx)? "TX": "RX"));
 				break;
 			default:
-				CFGP2P_ERR(("%s Unknown P2P Action Frame\n",
+				CFGP2P_DBG(("%s Unknown P2P Action Frame\n",
 					(tx)? "TX": "RX"));
 		}
 
@@ -209,23 +209,23 @@
 		sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
 		switch (sd_act_frm->action) {
 			case P2PSD_ACTION_ID_GAS_IREQ:
-				CFGP2P_ERR(("%s P2P GAS Initial Request\n",
+				CFGP2P_DBG(("%s P2P GAS Initial Request\n",
 					(tx)? "TX" : "RX"));
 				break;
 			case P2PSD_ACTION_ID_GAS_IRESP:
-				CFGP2P_ERR(("%s P2P GAS Initial Response\n",
+				CFGP2P_DBG(("%s P2P GAS Initial Response\n",
 					(tx)? "TX" : "RX"));
 				break;
 			case P2PSD_ACTION_ID_GAS_CREQ:
-				CFGP2P_ERR(("%s P2P GAS Comback Request\n",
+				CFGP2P_DBG(("%s P2P GAS Comback Request\n",
 					(tx)? "TX" : "RX"));
 				break;
 			case P2PSD_ACTION_ID_GAS_CRESP:
-				CFGP2P_ERR(("%s P2P GAS Comback Response\n",
+				CFGP2P_DBG(("%s P2P GAS Comback Response\n",
 					(tx)? "TX" : "RX"));
 				break;
 			default:
-				CFGP2P_ERR(("%s Unknown P2P GAS Frame\n",
+				CFGP2P_DBG(("%s Unknown P2P GAS Frame\n",
 					(tx)? "TX" : "RX"));
 		}
 
@@ -288,6 +288,7 @@
 	CFGP2P_DBG(("In\n"));
 	if (wl->p2p) {
 		kfree(wl->p2p);
+		wl->p2p = NULL;
 	}
 	wl->p2p_supported = 0;
 }
@@ -319,7 +320,7 @@
 	ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
 		sizeof(null_eth_addr), wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
 	if (ret && ret != BCME_UNSUPPORTED) {
-		CFGP2P_ERR(("failed to update device address\n"));
+		CFGP2P_ERR(("failed to update device address ret %d\n", ret));
 	}
 	return ret;
 }
@@ -343,7 +344,7 @@
 	ifreq.chspec = chspec;
 	memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet));
 
-	CFGP2P_INFO(("---wl p2p_ifadd %02x:%02x:%02x:%02x:%02x:%02x %s %u\n",
+	CFGP2P_DBG(("---wl p2p_ifadd %02x:%02x:%02x:%02x:%02x:%02x %s %u\n",
 	    ifreq.addr.octet[0], ifreq.addr.octet[1], ifreq.addr.octet[2],
 		ifreq.addr.octet[3], ifreq.addr.octet[4], ifreq.addr.octet[5],
 		(if_type == WL_P2P_IF_GO) ? "go" : "client",
@@ -483,7 +484,7 @@
 
 	/* Put the WL driver into P2P Listen Mode to respond to P2P probe reqs */
 	discovery_mode.state = mode;
-	discovery_mode.chspec = CH20MHZ_CHSPEC(channel);
+	discovery_mode.chspec = wl_ch_host_to_driver(channel);
 	discovery_mode.dwell = listen_ms;
 	ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_state", &discovery_mode,
 		sizeof(discovery_mode), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
@@ -540,7 +541,7 @@
 
 	/* Set the initial discovery state to SCAN */
 	ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
-	        wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+		wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
 
 	if (unlikely(ret != 0)) {
 		CFGP2P_ERR(("unable to set WL_P2P_DISC_ST_SCAN\n"));
@@ -691,7 +692,7 @@
 #define P2PAPI_SCAN_NPROBES 1
 #define P2PAPI_SCAN_DWELL_TIME_MS 50
 #define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40
-#define P2PAPI_SCAN_HOME_TIME_MS 10
+#define P2PAPI_SCAN_HOME_TIME_MS 60
 	struct net_device *pri_dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
 	wl_set_p2p_status(wl, SCANNING);
 	/* Allocate scan params which need space for 3 channels and 0 ssids */
@@ -757,7 +758,7 @@
 	    (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
 
 	for (i = 0; i < num_chans; i++) {
-		eparams->params.channel_list[i] = htodchanspec(channels[i]);
+		eparams->params.channel_list[i] = wl_ch_host_to_driver(channels[i]);
 	}
 	eparams->version = htod32(ESCAN_REQ_VERSION);
 	eparams->action =  htod16(action);
@@ -1920,11 +1921,7 @@
 	 * For Android PRIV CMD handling map it to primary I/F
 	 */
 	if (cmd == SIOCDEVPRIVATE+1) {
-#if defined(OEM_ANROID)
 		ret = wl_android_priv_cmd(ndev, ifr, cmd);
-#else
-	(void)ndev;
-#endif
 
 	} else {
 		CFGP2P_ERR(("%s: IOCTL req 0x%x on p2p0 I/F. Ignoring. \n",
@@ -1937,12 +1934,34 @@
 
 static int wl_cfgp2p_if_open(struct net_device *net)
 {
-	CFGP2P_DBG(("Do Nothing \n"));
+	struct wireless_dev *wdev = net->ieee80211_ptr;
+
+	if (!wdev)
+		return -EINVAL;
+
+	/* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now,
+	 * do it here. This will make sure that in concurrent mode, supplicant
+	 * is not dependent on a particular order of interface initialization.
+	 * i.e you may give wpa_supp -iwlan0 -N -ip2p0 or wpa_supp -ip2p0 -N
+	 * -iwlan0.
+	 */
+	wl_cfg80211_do_driver_init(net);
+
+	wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT)
+		| BIT(NL80211_IFTYPE_P2P_GO));
+
 	return 0;
 }
 
 static int wl_cfgp2p_if_stop(struct net_device *net)
 {
-	CFGP2P_DBG(("Do Nothing \n"));
+	struct wireless_dev *wdev = net->ieee80211_ptr;
+
+	if (!wdev)
+		return -EINVAL;
+
+	wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes)
+					& (~(BIT(NL80211_IFTYPE_P2P_CLIENT)|
+					BIT(NL80211_IFTYPE_P2P_GO)));
 	return 0;
 }
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
index eb15d44..427cb4a 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.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_cfgp2p.h 308397 2012-01-15 07:32:58Z $
+ * $Id: wl_cfgp2p.h 316197 2012-02-21 13:16:39Z $
  */
 #ifndef _wl_cfgp2p_h_
 #define _wl_cfgp2p_h_
@@ -269,7 +269,7 @@
 #define WL_P2P_WILDCARD_SSID "DIRECT-"
 #define WL_P2P_WILDCARD_SSID_LEN 7
 #define WL_P2P_INTERFACE_PREFIX "p2p"
-#define WL_P2P_TEMP_CHAN "11"
+#define WL_P2P_TEMP_CHAN 11
 
 
 #define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \
diff --git a/drivers/net/wireless/bcmdhd/wl_dbg.h b/drivers/net/wireless/bcmdhd/wl_dbg.h
index ce73a27..7050508 100644
--- a/drivers/net/wireless/bcmdhd/wl_dbg.h
+++ b/drivers/net/wireless/bcmdhd/wl_dbg.h
@@ -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: wl_dbg.h 308108 2012-01-13 12:26:08Z $
+ * $Id: wl_dbg.h 324578 2012-03-29 21:30:09Z $
  */
 
 
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c
index 4f8a76f..be08025 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/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 302026 2011-12-09 11:51:50Z $
+ * $Id: wl_iw.c 312290 2012-02-02 02:52:18Z $
  */
 
 #if defined(USE_IW)
@@ -150,12 +150,21 @@
 static void wl_iw_set_event_mask(struct net_device *dev);
 static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
-#define IW_DEV_IF(dev)        ((wl_iw_t *)netdev_priv(dev))
+
+typedef struct priv_link {
+	wl_iw_t *wliw;
+} priv_link_t;
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
+#define WL_DEV_LINK(dev)       (priv_link_t*)(dev->priv)
 #else
-#define IW_DEV_IF(dev)        ((wl_iw_t *)dev->priv)
+#define WL_DEV_LINK(dev)       (priv_link_t*)netdev_priv(dev)
 #endif
 
+
+#define IW_DEV_IF(dev)          ((wl_iw_t*)(WL_DEV_LINK(dev))->wliw)
+
 static void swap_key_from_BE(
 	        wl_wsec_key_t *key
 )
diff --git a/drivers/net/wireless/bcmdhd/wl_linux_mon.c b/drivers/net/wireless/bcmdhd/wl_linux_mon.c
index ab6d6f4..af25863 100644
--- a/drivers/net/wireless/bcmdhd/wl_linux_mon.c
+++ b/drivers/net/wireless/bcmdhd/wl_linux_mon.c
@@ -89,12 +89,12 @@
 	.ndo_open		= dhd_mon_if_open,
 	.ndo_stop		= dhd_mon_if_stop,
 	.ndo_start_xmit		= dhd_mon_if_subif_start_xmit,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
-	.ndo_set_rx_mode	= dhd_mon_if_set_multicast_list,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
+	.ndo_set_rx_mode = dhd_mon_if_set_multicast_list,
 #else
 	.ndo_set_multicast_list = dhd_mon_if_set_multicast_list,
 #endif
-	.ndo_set_mac_address	= dhd_mon_if_change_mac,
+	.ndo_set_mac_address 	= dhd_mon_if_change_mac,
 };
 
 /**
@@ -231,6 +231,7 @@
 		pdata = (unsigned char*)skb->data;
 		memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
 		memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
+		PKTSETPRIO(skb, 0);
 
 		MON_PRINT("if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name);