From b2fdbcd3116c1e365bd3988636eacb8c2c3ad28b Mon Sep 17 00:00:00 2001
From: Howard M. Harte <hharte@broadcom.com>
Date: Fri, 10 Jun 2011 17:20:12 -0700
Subject: [PATCH 290/696] Update to 5.90.125.27 release.

Change-Id: I593f4a90671468b486e5f39b9eeff8ae65ac9431
Signed-off-by: Howard M. Harte <hharte@broadcom.com>
---
 drivers/net/wireless/bcmdhd/dhd_cdc.c          |    4 +-
 drivers/net/wireless/bcmdhd/dhd_common.c       |   39 ++--
 drivers/net/wireless/bcmdhd/dhd_dbg.h          |    4 +
 drivers/net/wireless/bcmdhd/dhd_linux.c        |  312 ++++++++++++++++++++----
 drivers/net/wireless/bcmdhd/dhd_sdio.c         |   20 +-
 drivers/net/wireless/bcmdhd/include/bcmdefs.h  |    2 -
 drivers/net/wireless/bcmdhd/include/dhdioctl.h |    1 +
 drivers/net/wireless/bcmdhd/include/epivers.h  |    8 +-
 drivers/net/wireless/bcmdhd/include/wlioctl.h  |   14 +-
 drivers/net/wireless/bcmdhd/wl_cfg80211.c      |  213 +++++++----------
 drivers/net/wireless/bcmdhd/wl_cfg80211.h      |   69 +-----
 drivers/net/wireless/bcmdhd/wl_cfgp2p.c        |  125 +++-------
 drivers/net/wireless/bcmdhd/wl_cfgp2p.h        |  107 ++++++++-
 drivers/net/wireless/bcmdhd/wl_iw.c            |   10 +-
 drivers/net/wireless/bcmdhd/wl_iw.h            |    5 +-
 15 files changed, 560 insertions(+), 373 deletions(-)

diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c
index fb0d5ad..44a431b 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -116,7 +116,7 @@ dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len)
 	return ret;
 }
 
-int
+static int
 dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
 {
 	dhd_prot_t *prot = dhd->prot;
@@ -203,7 +203,7 @@ done:
 	return ret;
 }
 
-int
+static int
 dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
 {
 	dhd_prot_t *prot = dhd->prot;
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index 811d9ce..0bc2eb2 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -204,12 +204,12 @@ dhd_common_init(osl_t *osh)
 
 #ifdef CONFIG_BCMDHD_FW_PATH
 	bcm_strncpy_s(fw_path, sizeof(fw_path), CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
-#else
+#else /* CONFIG_BCMDHD_FW_PATH */
 	fw_path[0] = '\0';
 #endif /* CONFIG_BCMDHD_FW_PATH */
 #ifdef CONFIG_BCMDHD_NVRAM_PATH
 	bcm_strncpy_s(nv_path, sizeof(nv_path), CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
-#else
+#else /* CONFIG_BCMDHD_NVRAM_PATH */
 	nv_path[0] = '\0';
 #endif /* CONFIG_BCMDHD_NVRAM_PATH */
 #ifdef SOFTAP
@@ -568,7 +568,7 @@ dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec)
 	else if (pktq_full(q)) {
 		p = pktq_peek_tail(q, &eprec);
 		ASSERT(p);
-		if (eprec > prec)
+		if (eprec > prec || eprec < 0)
 			return FALSE;
 	}
 
@@ -1541,7 +1541,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 	int						str_len;
 	uint32					mask_size;
 	uint32					pattern_size;
-	char buf[256];
+	char buf[WLC_IOCTL_SMLEN];
 	char *ptr;
 	uint filter_mode = 1;
 	uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
@@ -1624,11 +1624,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 	memset(buf, 0, sizeof(buf));
 	ptr = buf;
 	bcm_mkiovar("ver", (char *)&buf, 4, buf, sizeof(buf));
-	dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), TRUE, 0);
-	bcmstrtok(&ptr, "\n", 0);
-	/* Print fw version info */
-	DHD_ERROR(("Firmware version = %s\n", buf));
-
+	if ((ret  = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0)
+		DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
+	else {
+		bcmstrtok(&ptr, "\n", 0);
+		/* Print fw version info */
+		DHD_ERROR(("Firmware version = %s\n", buf));
+	}
 	/* Set PowerSave mode */
 	dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
 
@@ -1989,8 +1991,8 @@ int
 dhd_get_dtim_skip(dhd_pub_t *dhd)
 {
 	int bcn_li_dtim;
-	char buf[128];
 	int ret;
+	uint8 bssid[6];
 	int dtim_assoc = 0;
 
 	if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
@@ -1998,16 +2000,19 @@ dhd_get_dtim_skip(dhd_pub_t *dhd)
 	else
 		bcn_li_dtim = dhd->dtim_skip;
 
-	/* Read DTIM value if associated */
-	memset(buf, 0, sizeof(buf));
-	bcm_mkiovar("dtim_assoc", 0, 0, buf, sizeof(buf));
-	if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0)) < 0) {
+	/* Check if associated */
+	if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID,
+		(char *)&bssid, ETHER_ADDR_LEN, FALSE, 0)) == BCME_NOTASSOCIATED) {
+		DHD_TRACE(("%s NOT assoc ret %d\n", __FUNCTION__, ret));
+		goto exit;
+	}
+
+	/* if assoc grab ap's dtim value */
+	if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_DTIMPRD,
+		&dtim_assoc, sizeof(dtim_assoc), FALSE, 0)) < 0) {
 		DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
-		bcn_li_dtim = 1;
 		goto exit;
 	}
-	else
-		dtim_assoc = dtoh32(*(int *)buf);
 
 	DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n",
 		__FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL));
diff --git a/drivers/net/wireless/bcmdhd/dhd_dbg.h b/drivers/net/wireless/bcmdhd/dhd_dbg.h
index 8bbfc1e..10851c4 100644
--- a/drivers/net/wireless/bcmdhd/dhd_dbg.h
+++ b/drivers/net/wireless/bcmdhd/dhd_dbg.h
@@ -43,6 +43,7 @@
 #define DHD_EVENT(args)		do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0)
 #define DHD_BTA(args)		do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0)
 #define DHD_ISCAN(args)		do {if (dhd_msg_level & DHD_ISCAN_VAL) printf args;} while (0)
+#define DHD_ARPOE(args)		do {if (dhd_msg_level & DHD_ARPOE_VAL) printf args;} while (0)
 
 #define DHD_ERROR_ON()		(dhd_msg_level & DHD_ERROR_VAL)
 #define DHD_TRACE_ON()		(dhd_msg_level & DHD_TRACE_VAL)
@@ -57,6 +58,7 @@
 #define DHD_EVENT_ON()		(dhd_msg_level & DHD_EVENT_VAL)
 #define DHD_BTA_ON()		(dhd_msg_level & DHD_BTA_VAL)
 #define DHD_ISCAN_ON()		(dhd_msg_level & DHD_ISCAN_VAL)
+#define DHD_ARPOE_ON()		(dhd_msg_level & DHD_ARPOE_VAL)
 
 #else /* defined(BCMDBG) || defined(DHD_DEBUG) */
 
@@ -73,6 +75,7 @@
 #define DHD_EVENT(args)
 #define DHD_BTA(args)
 #define DHD_ISCAN(args)
+#define DHD_ARPOE(args)
 
 #define DHD_ERROR_ON()		0
 #define DHD_TRACE_ON()		0
@@ -87,6 +90,7 @@
 #define DHD_EVENT_ON()		0
 #define DHD_BTA_ON()		0
 #define DHD_ISCAN_ON()		0
+#define DHD_ARPOE_ON()		0
 #endif 
 
 #define DHD_LOG(args)
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 8513fcc..6886544 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -24,6 +24,10 @@
  *
  * $Id: dhd_linux.c,v 1.131.2.55 2011-02-09 05:31:56 Exp $
  */
+
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+#include <linux/platform_device.h>
+#endif
 #include <typedefs.h>
 #include <linuxver.h>
 #include <osl.h>
@@ -33,6 +37,8 @@
 #include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
 #include <linux/etherdevice.h>
 #include <linux/random.h>
 #include <linux/spinlock.h>
@@ -75,7 +81,6 @@
 
 static uint32 tsidx = 0;
 static uint32 htsf_seqnum = 0;
-
 uint32 tsfsync;
 struct timeval tsync;
 static uint32 tsport = 5010;
@@ -87,13 +92,20 @@ typedef struct histo_ {
 static histo_t vi_d1, vi_d2, vi_d3, vi_d4;
 #endif /* WLMEDIA_HTSF */
 
+#if defined(ANDROID) && defined(SOFTAP)
+extern bool	ap_cfg_running;
+#endif
+
+/* enable HOSTIP cache update from the host side when an eth0:N is up */
+#define AOE_IP_ALIAS_SUPPORT 1
+
 #ifdef PROP_TXSTATUS
 #include <wlfc_proto.h>
 #include <dhd_wlfc.h>
 #endif
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+
 
-#ifdef CONFIG_WIFI_CONTROL_FUNC
-#include <linux/platform_device.h>
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
 #include <linux/wlan_plat.h>
 #else
@@ -101,6 +113,7 @@ static histo_t vi_d1, vi_d2, vi_d3, vi_d4;
 #endif
 
 struct semaphore wifi_control_sem;
+struct dhd_bus *g_bus;
 
 static struct wifi_platform_data *wifi_control_data = NULL;
 static struct resource *wifi_irqres = NULL;
@@ -169,6 +182,9 @@ static int wifi_probe(struct platform_device *pdev)
 
 	DHD_ERROR(("## %s\n", __FUNCTION__));
 	wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
+	if (wifi_irqres == NULL)
+		wifi_irqres = platform_get_resource_byname(pdev,
+			IORESOURCE_IRQ, "bcm4329_wlan_irq");
 	wifi_control_data = wifi_ctrl;
 
 	wifi_set_power(1, 0);	/* Power On */
@@ -202,7 +218,6 @@ static int wifi_resume(struct platform_device *pdev)
 	DHD_TRACE(("##> %s\n", __FUNCTION__));
 	return 0;
 }
-
 static struct platform_driver wifi_device = {
 	.probe          = wifi_probe,
 	.remove         = wifi_remove,
@@ -213,19 +228,42 @@ static struct platform_driver wifi_device = {
 	}
 };
 
+static struct platform_driver wifi_device_legacy = {
+	.probe          = wifi_probe,
+	.remove         = wifi_remove,
+	.suspend        = wifi_suspend,
+	.resume         = wifi_resume,
+	.driver         = {
+	.name   = "bcm4329_wlan",
+	}
+};
+
 int wifi_add_dev(void)
 {
 	DHD_TRACE(("## Calling platform_driver_register\n"));
-	return platform_driver_register(&wifi_device);
+	platform_driver_register(&wifi_device);
+	platform_driver_register(&wifi_device_legacy);
+	return 0;
 }
 
 void wifi_del_dev(void)
 {
 	DHD_TRACE(("## Unregister platform_driver_register\n"));
 	platform_driver_unregister(&wifi_device);
+	platform_driver_unregister(&wifi_device_legacy);
 }
 #endif
 
+#ifdef ARP_OFFLOAD_SUPPORT
+static int dhd_device_event(struct notifier_block *this,
+	unsigned long event,
+	void *ptr);
+
+static struct notifier_block dhd_notifier = {
+	.notifier_call = dhd_device_event
+};
+#endif /* ARP_OFFLOAD_SUPPORT */
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
 #include <linux/suspend.h>
 volatile bool dhd_mmc_suspend = FALSE;
@@ -529,7 +567,7 @@ module_param(dhd_pktgen_len, uint, 0);
 #define DHD_COMPILED "\nCompiled in " SRCBASE
 #else
 #define DHD_COMPILED
-#endif
+#endif /* DHD_DEBUG */
 
 static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR
 #ifdef DHD_DEBUG
@@ -617,7 +655,6 @@ static void dhd_set_packet_filter(int value, dhd_pub_t *dhd)
 }
 
 #if defined(CONFIG_HAS_EARLYSUSPEND)
-extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
 static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 {
 	int power_mode = PM_MAX;
@@ -1042,6 +1079,11 @@ dhd_op_if(dhd_if_t *ifp)
 
 	DHD_TRACE(("%s: idx %d, state %d\n", __FUNCTION__, ifp->idx, ifp->state));
 
+#ifdef WL_CFG80211
+	if (wl_cfg80211_is_progress_ifchange())
+			return;
+
+#endif
 	switch (ifp->state) {
 	case WLC_E_IF_ADD:
 		/*
@@ -1062,6 +1104,11 @@ dhd_op_if(dhd_if_t *ifp)
 		}
 		if (ret == 0) {
 			strncpy(ifp->net->name, ifp->name, IFNAMSIZ);
+#ifdef WL_CFG80211
+			if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+				wl_cfg80211_notify_ifadd(ifp->net);
+#endif
+
 			ifp->net->name[IFNAMSIZ - 1] = '\0';
 			memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
 			if ((err = dhd_net_attach(&dhd->pub, ifp->idx)) != 0) {
@@ -1069,7 +1116,8 @@ dhd_op_if(dhd_if_t *ifp)
 					__FUNCTION__, err));
 				ret = -EOPNOTSUPP;
 			} else {
-#ifdef SOFTAP
+#if defined(ANDROID) && defined(SOFTAP)
+		if (ap_cfg_running && !(dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) {
 				 /* semaphore that the soft AP CODE waits on */
 				flags = dhd_os_spin_lock(&dhd->pub);
 
@@ -1078,6 +1126,7 @@ dhd_op_if(dhd_if_t *ifp)
 				 /* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */
 				up(&ap_eth_ctl.sema);
 				dhd_os_spin_unlock(&dhd->pub, flags);
+		}
 #endif
 				DHD_TRACE(("\n ==== pid:%x, net_device for if:%s created ===\n\n",
 					current->pid, ifp->net->name));
@@ -1105,6 +1154,10 @@ dhd_op_if(dhd_if_t *ifp)
 		}
 		dhd->iflist[ifp->idx] = NULL;
 		MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
+#ifdef WL_CFG80211
+		if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+			wl_cfg80211_notify_ifdel(ifp->net);
+#endif
 #ifdef SOFTAP
 		flags = dhd_os_spin_lock(&dhd->pub);
 		if (ifp->net == ap_net_dev)
@@ -1138,6 +1191,7 @@ _dhd_sysioc_thread(void *data)
 			break;
 		}
 
+
 		for (i = 0; i < DHD_MAX_IFS; i++) {
 			if (dhd->iflist[i]) {
 				DHD_TRACE(("%s: interface %d\n", __FUNCTION__, i));
@@ -1179,6 +1233,7 @@ _dhd_sysioc_thread(void *data)
 				}
 			}
 		}
+
 		DHD_OS_WAKE_UNLOCK(&dhd->pub);
 	}
 	DHD_TRACE(("%s: stopped\n", __FUNCTION__));
@@ -1533,7 +1588,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
 		skb_pull(skb, ETH_HLEN);
 
 		/* Process special event packets and then discard them */
-		if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM)
+		if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) {
 			dhd_wl_host_event(dhd, &ifidx,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
 			skb->mac_header,
@@ -1547,6 +1602,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
 			if (event.event_type == WLC_E_BTA_HCI_EVENT) {
 				dhd_bta_doevt(dhdp, data, event.datalen);
 			}
+		}
 
 
 		ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
@@ -2236,12 +2292,12 @@ dhd_stop(struct net_device *net)
 	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
 
 	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
-#ifdef WL_CFG80211
-	wl_cfg80211_down();
-#endif
 	if (dhd->pub.up == 0) {
 		return 0;
 	}
+#ifdef WL_CFG80211
+	wl_cfg80211_down();
+#endif
 
 #ifdef PROP_TXSTATUS
 	dhd_wlfc_cleanup(&dhd->pub);
@@ -2268,10 +2324,10 @@ dhd_open(struct net_device *net)
 	int ifidx;
 	int32 ret = 0;
 
-#if defined(OEM_ANDROID) && !defined(WL_CFG80211)
+#if !defined(WL_CFG80211)
 	/*  Force start if ifconfig_up gets called before START command */
 	wl_control_wl_start(net);
-#endif /* defined(OEM_ANDROID) && !defined(WL_CFG80211) */
+#endif
 
 	ifidx = dhd_net2idx(dhd, net);
 	DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
@@ -2405,6 +2461,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
 	dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT;
 	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
+
 	/* updates firmware nvram path if it was provided as module parameters */
 	if ((firmware_path != NULL) && (firmware_path[0] != '\0'))
 		strcpy(fw_path, firmware_path);
@@ -2501,15 +2558,6 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
 	}
 	dhd_state |= DHD_ATTACH_STATE_PROT_ATTACH;
 
-#if defined(CONFIG_WIRELESS_EXT)
-	/* Attach and link in the iw */
-	if (wl_iw_attach(net, (void *)&dhd->pub) != 0) {
-		DHD_ERROR(("wl_iw_attach failed\n"));
-		goto fail;
-	}
-	dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
-#endif /* defined(CONFIG_WIRELESS_EXT) */
-
 #ifdef WL_CFG80211
 	/* Attach and link in the cfg80211 */
 	if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) {
@@ -2518,6 +2566,18 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
 	}
 	dhd_state |= DHD_ATTACH_STATE_CFG80211;
 #endif
+#if defined(CONFIG_WIRELESS_EXT)
+	/* Attach and link in the iw */
+	if (!(dhd_state &  DHD_ATTACH_STATE_CFG80211)) {
+		if (wl_iw_attach(net, (void *)&dhd->pub) != 0) {
+			DHD_ERROR(("wl_iw_attach failed\n"));
+			goto fail;
+		}
+	dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
+	}
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+
 	/* Set up the watchdog timer */
 	init_timer(&dhd->timer);
 	dhd->timer.data = (ulong)dhd;
@@ -2567,6 +2627,9 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
 	 */
 	memcpy(netdev_priv(net), &dhd, sizeof(dhd));
 
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+	g_bus = bus;
+#endif
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) && 1
 	register_pm_notifier(&dhd_sleep_pm_notifier);
 #endif /*  (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
@@ -2578,6 +2641,11 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
 	register_early_suspend(&dhd->early_suspend);
 	dhd_state |= DHD_ATTACH_STATE_EARLYSUSPEND_DONE;
 #endif
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	register_inetaddr_notifier(&dhd_notifier);
+#endif /* ARP_OFFLOAD_SUPPORT */
+
 	dhd_state |= DHD_ATTACH_STATE_DONE;
 	dhd->dhd_state = dhd_state;
 	return &dhd->pub;
@@ -2593,6 +2661,7 @@ fail:
 		dhd_free(&dhd->pub);
 	}
 
+
 	return NULL;
 }
 
@@ -2684,7 +2753,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
 	setbit(dhdp->eventmask, WLC_E_TXFAIL);
 	setbit(dhdp->eventmask, WLC_E_JOIN_START);
 	setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE);
-	setbit(dhdp->eventmask, WLC_E_RELOAD);
+
 #ifdef PNO_SUPPORT
 	setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND);
 #endif /* PNO_SUPPORT */
@@ -2707,10 +2776,13 @@ dhd_bus_start(dhd_pub_t *dhdp)
 		return ret;
 
 #ifdef WRITE_MACADDR
-	/* it could be used even when WIFI is not Enabled [ON] */
 	dhd_write_macaddr(dhd->pub.mac.octet);
 #endif
 
+#if defined(CONFIG_SYSCTL) && defined(WL_CFG80211)
+	wl_cfg80211_sysctl_export_devaddr(&dhd->pub);
+#endif
+
 	return 0;
 }
 
@@ -2783,6 +2855,115 @@ int dhd_change_mtu(dhd_pub_t *dhdp, int new_mtu, int ifidx)
 	return 0;
 }
 
+#ifdef ARP_OFFLOAD_SUPPORT
+/* add or remove AOE host ip(s) (up to 8 IPs on the interface)  */
+void aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add)
+{
+	u32 ipv4_buf[8]; /* temp save for AOE host_ip table */
+	int i;
+
+	bzero(ipv4_buf, sizeof(ipv4_buf));
+
+	/* display what we've got */
+	dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf));
+	DHD_ARPOE(("%s: hostip table read from Dongle:\n", __FUNCTION__));
+	dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */
+
+	/* now we saved hoste_ip table, clr it in the dongle AOE */
+	dhd_aoe_hostip_clr(dhd_pub);
+
+	for (i = 0; i < 8; i++) {
+
+		if (add && (ipv4_buf[i] == 0)) {
+
+				ipv4_buf[i]	= ipa;
+				add = FALSE; /* added ipa to local table  */
+				DHD_ARPOE(("%s: Saved new IP in temp arp_hostip[%d]\n",
+				__FUNCTION__, i));
+
+		} else if (ipv4_buf[i] == ipa) {
+			ipv4_buf[i]	= 0;
+			DHD_ARPOE(("%s: removed IP:%x from temp table %d\n",
+				__FUNCTION__, ipa, i));
+		}
+
+		if (ipv4_buf[i] != 0) {
+			/* add back host_ip entries from our local cache */
+			dhd_arp_offload_add_ip(dhd_pub, ipv4_buf[i]);
+			DHD_ARPOE(("%s: added IP:%x to dongle arp_hostip[%d]\n\n",
+				__FUNCTION__, ipv4_buf[i], i));
+		}
+	}
+#ifdef AOE_DBG
+	/* see the resulting hostip table */
+	dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf));
+	DHD_ARPOE(("%s: read back arp_hostip table:\n", __FUNCTION__));
+	dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */
+#endif
+}
+
+static int dhd_device_event(struct notifier_block *this,
+	unsigned long event,
+	void *ptr)
+{
+	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+
+	dhd_info_t *dhd;
+	dhd_pub_t *dhd_pub;
+
+	if (!ifa)
+		return NOTIFY_DONE;
+
+	dhd = *(dhd_info_t **)netdev_priv(ifa->ifa_dev->dev);
+	dhd_pub = &dhd->pub;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
+	if (ifa->ifa_dev->dev->netdev_ops == &dhd_ops_pri) {
+#else
+	if (ifa->ifa_dev->dev) {
+#endif
+		switch (event) {
+		case NETDEV_UP:
+			DHD_ARPOE(("%s: [%s] Up IP: 0x%x\n",
+				__FUNCTION__, ifa->ifa_label, ifa->ifa_address));
+
+#ifdef AOE_IP_ALIAS_SUPPORT
+			if (ifa->ifa_label[strlen(ifa->ifa_label)-2] == 0x3a) {
+				DHD_ARPOE(("%s:add aliased IP to AOE hostip cache\n",
+					__FUNCTION__));
+				aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE);
+			}
+#endif
+			break;
+
+		case NETDEV_DOWN:
+			DHD_ARPOE(("%s: [%s] Down IP: 0x%x\n",
+				__FUNCTION__, ifa->ifa_label, ifa->ifa_address));
+
+#ifdef AOE_IP_ALIAS_SUPPORT
+		if (!(ifa->ifa_label[strlen(ifa->ifa_label)-2] == 0x3a)) {
+				DHD_ARPOE(("%s: primary interface is down, AOE clr all\n",
+					__FUNCTION__));
+				dhd_aoe_hostip_clr(&dhd->pub);
+				dhd_aoe_arp_clr(&dhd->pub);
+		} else
+			aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE);
+#else
+	dhd_aoe_hostip_clr(&dhd->pub);
+	dhd_aoe_arp_clr(&dhd->pub);
+#endif
+			break;
+
+		default:
+			DHD_ARPOE(("%s: do noting for [%s] Event: %lu\n",
+				__func__, ifa->ifa_label, event));
+			break;
+		}
+	}
+	return NOTIFY_DONE;
+}
+#endif /* ARP_OFFLOAD_SUPPORT */
+
 int
 dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
 {
@@ -2855,24 +3036,24 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
 		DHD_ERROR(("couldn't register the net device, err %d\n", err));
 		goto fail;
 	}
+#if defined(WL_CFG80211)
+	if (ifidx == 0)
+		wl_cfg80211_attach_post(net);
+#endif
 
 	printf("%s: Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", net->name,
 	       dhd->pub.mac.octet[0], dhd->pub.mac.octet[1], dhd->pub.mac.octet[2],
 	       dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]);
 
-#if defined(CONFIG_WIRELESS_EXT)
-#ifdef SOFTAP
-	if (ifidx == 0)
-		/* Don't call for SOFTAP Interface in SOFTAP MODE */
-		wl_iw_iscan_set_scan_broadcast_prep(net, 1);
-#else
+#if defined(SOFTAP) && defined(CONFIG_WIRELESS_EXT) && !defined(WL_CFG80211)
 		wl_iw_iscan_set_scan_broadcast_prep(net, 1);
-#endif /* SOFTAP */
-#endif /* CONFIG_WIRELESS_EXT */
+#endif
 
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
-	up(&dhd_registration_sem);
+	if (ifidx == 0) {
+		up(&dhd_registration_sem);
+	}
 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
 	return 0;
 
@@ -2929,6 +3110,10 @@ void dhd_detach(dhd_pub_t *dhdp)
 		osl_delay(1000*100);
 	}
 
+#ifdef ARP_OFFLOAD_SUPPORT
+	unregister_inetaddr_notifier(&dhd_notifier);
+#endif /* ARP_OFFLOAD_SUPPORT */
+
 #if defined(CONFIG_HAS_EARLYSUSPEND)
 	if (dhd->dhd_state & DHD_ATTACH_STATE_EARLYSUSPEND_DONE) {
 		if (dhd->early_suspend.suspend)
@@ -2944,11 +3129,6 @@ void dhd_detach(dhd_pub_t *dhdp)
 	}
 #endif /* defined(CONFIG_WIRELESS_EXT) */
 
-#ifdef WL_CFG80211
-	if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
-		wl_cfg80211_detach();
-#endif
-
 	if (&dhd->thr_sysioc_ctl.thr_pid >= 0) {
 		PROC_STOP(&dhd->thr_sysioc_ctl);
 	}
@@ -2979,7 +3159,7 @@ void dhd_detach(dhd_pub_t *dhdp)
 			unregister_netdev(ifp->net);
 			MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
 
-	}
+		}
 	}
 
 	/* Clear the watchdog timer */
@@ -3005,7 +3185,10 @@ void dhd_detach(dhd_pub_t *dhdp)
 		if (dhdp->prot)
 			dhd_prot_detach(dhdp);
 	}
-
+#ifdef WL_CFG80211
+	if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+		wl_cfg80211_detach();
+#endif
 
 	if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) {
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
@@ -3097,6 +3280,7 @@ dhd_module_init(void)
 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
 	error = dhd_bus_register();
 
+
 	if (!error)
 		printf("\n%s\n", dhd_version);
 	else {
@@ -3451,22 +3635,37 @@ dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
 		return (bcmerror);
 
 #if defined(CONFIG_WIRELESS_EXT)
-	ASSERT(dhd->iflist[*ifidx] != NULL);
+	if (event->bsscfgidx == 0) {
+		/*
+		 * Wireless ext is on primary interface only
+		 */
 
-	/*
-	 * Wireless ext is on primary interface only
-	 */
-	if (dhd->iflist[*ifidx]->net && (event->bsscfgidx == 0))
-		wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
+		ASSERT(dhd->iflist[*ifidx] != NULL);
+		ASSERT(dhd->iflist[*ifidx]->net != NULL);
 
+		if (dhd->iflist[*ifidx]->net) {
+			wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
+		}
+	}
 #endif /* defined(CONFIG_WIRELESS_EXT)  */
 
 #ifdef WL_CFG80211
+
+	if ((wl_cfg80211_is_progress_ifchange() ||
+		wl_cfg80211_is_progress_ifadd()) && (*ifidx != 0)) {
+		/*
+		 * If IF_ADD/CHANGE operation is going on,
+		 *  discard any event received on the virtual I/F
+		 */
+		return (BCME_OK);
+	}
+
 	ASSERT(dhd->iflist[*ifidx] != NULL);
 	ASSERT(dhd->iflist[*ifidx]->net != NULL);
-	if (dhd->iflist[*ifidx]->net)
-		wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, *data, GFP_ATOMIC);
-#endif
+	if (dhd->iflist[*ifidx]->net) {
+		wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, *data);
+	}
+#endif /* defined(WL_CFG80211) */
 
 	return (bcmerror);
 }
@@ -3600,20 +3799,25 @@ void dhd_wait_event_wakeup(dhd_pub_t *dhd)
 int
 dhd_dev_reset(struct net_device *dev, uint8 flag)
 {
+	int ret;
+
 	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
 
 	/* Turning off watchdog */
 	if (flag)
 		dhd_os_wd_timer(&dhd->pub, 0);
 
-	dhd_bus_devreset(&dhd->pub, flag);
-
+	ret = dhd_bus_devreset(&dhd->pub, flag);
+	if (ret) {
+		DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret));
+		return ret;
+	}
 	/* Turning on watchdog back */
 	if (!flag)
 		dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
 	DHD_ERROR(("%s:  WLAN OFF DONE\n", __FUNCTION__));
 
-	return 1;
+	return ret;
 }
 
 int net_os_set_suspend_disable(struct net_device *dev, int val)
@@ -3742,7 +3946,7 @@ void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec)
 	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
 
 	if (dhd && dhd->pub.up)
-		memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t));
+			memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t));
 }
 
 
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index c51b832..f3e53bf 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -5610,11 +5610,11 @@ dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh)
 
 bool
 dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
-                          char *fw_path, char *nv_path)
+                          char *pfw_path, char *pnv_path)
 {
 	bool ret;
-	bus->fw_path = fw_path;
-	bus->nv_path = nv_path;
+	bus->fw_path = pfw_path;
+	bus->nv_path = pnv_path;
 
 	ret = dhdsdio_download_firmware(bus, osh, bus->sdh);
 
@@ -5858,7 +5858,7 @@ err:
 #endif /* BCMEMBEDIMAGE */
 
 static int
-dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path)
+dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path)
 {
 	int bcmerror = -1;
 	int offset = 0;
@@ -5866,9 +5866,9 @@ dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path)
 	void *image = NULL;
 	uint8 *memblock = NULL, *memptr;
 
-	DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, fw_path));
+	DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, pfw_path));
 
-	image = dhd_os_open_image(fw_path);
+	image = dhd_os_open_image(pfw_path);
 	if (image == NULL)
 		goto err;
 
@@ -5930,17 +5930,17 @@ dhdsdio_download_nvram(struct dhd_bus *bus)
 	void * image = NULL;
 	char * memblock = NULL;
 	char *bufp;
-	char *nv_path;
+	char *pnv_path;
 	bool nvram_file_exists;
 
-	nv_path = bus->nv_path;
+	pnv_path = bus->nv_path;
 
-	nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0'));
+	nvram_file_exists = ((pnv_path != NULL) && (pnv_path[0] != '\0'));
 	if (!nvram_file_exists && (bus->nvram_params == NULL))
 		return (0);
 
 	if (nvram_file_exists) {
-		image = dhd_os_open_image(nv_path);
+		image = dhd_os_open_image(pnv_path);
 		if (image == NULL)
 			goto err;
 	}
diff --git a/drivers/net/wireless/bcmdhd/include/bcmdefs.h b/drivers/net/wireless/bcmdhd/include/bcmdefs.h
index 6b92ebc..da1fd5e 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmdefs.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmdefs.h
@@ -155,8 +155,6 @@ typedef struct {
 #if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY)
 
 #define BCMEXTRAHDROOM 220
-#elif defined(BCM43237) && defined(BCMPKTPOOL) && defined(DMATXRC)
-#define BCMEXTRAHDROOM 0
 #else
 #define BCMEXTRAHDROOM 172
 #endif
diff --git a/drivers/net/wireless/bcmdhd/include/dhdioctl.h b/drivers/net/wireless/bcmdhd/include/dhdioctl.h
index abe4efb..9661dac 100644
--- a/drivers/net/wireless/bcmdhd/include/dhdioctl.h
+++ b/drivers/net/wireless/bcmdhd/include/dhdioctl.h
@@ -86,6 +86,7 @@ enum {
 #define DHD_EVENT_VAL	0x0800
 #define DHD_BTA_VAL	0x1000
 #define DHD_ISCAN_VAL	0x2000
+#define DHD_ARPOE_VAL	0x4000
 
 #ifdef SDTEST
 /* For pktgen iovar */
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index 9a79a1e..9ef7703 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -33,17 +33,17 @@
 
 #define	EPI_RC_NUMBER		125
 
-#define	EPI_INCREMENTAL_NUMBER	22
+#define	EPI_INCREMENTAL_NUMBER	27
 
 #define	EPI_BUILD_NUMBER	0
 
-#define	EPI_VERSION		5, 90, 125, 22
+#define	EPI_VERSION		5, 90, 125, 27
 
-#define	EPI_VERSION_NUM		0x055a7d16
+#define	EPI_VERSION_NUM		0x055a7d1b
 
 #define EPI_VERSION_DEV		5.90.125
 
 
-#define	EPI_VERSION_STR		"5.90.125.22"
+#define	EPI_VERSION_STR		"5.90.125.27"
 
 #endif 
diff --git a/drivers/net/wireless/bcmdhd/include/wlioctl.h b/drivers/net/wireless/bcmdhd/include/wlioctl.h
index d78ecfc..e57d218 100644
--- a/drivers/net/wireless/bcmdhd/include/wlioctl.h
+++ b/drivers/net/wireless/bcmdhd/include/wlioctl.h
@@ -63,6 +63,12 @@ typedef struct wl_action_frame {
 
 #define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame)
 
+typedef struct ssid_info
+{
+	uint8		ssid_len;
+	uint8		ssid[32];
+} ssid_info_t;
+
 typedef struct wl_af_params {
 	uint32          channel;
 	int32           dwell_time;
@@ -638,12 +644,14 @@ typedef struct wl_assoc_info {
 	uint32      resp_len;
 	uint32      flags;
 	struct dot11_assoc_req req;
-	struct ether_addr reassoc_bssid; /* used in reassoc's */
+	struct ether_addr reassoc_bssid;
 	struct dot11_assoc_resp resp;
 } wl_assoc_info_t;
 
-/* flags */
-#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */
+
+#define WLC_ASSOC_REQ_IS_REASSOC 0x01
+
+
 
 #define WLC_TXFILTER_OVERRIDE_DISABLED  0
 #define WLC_TXFILTER_OVERRIDE_ENABLED   1
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index f2480e9..aeef88d 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -199,7 +199,7 @@ static void wl_init_eq_lock(struct wl_priv *wl);
 static void wl_init_event_handler(struct wl_priv *wl);
 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
 static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
-	const wl_event_msg_t *msg, void *data, gfp_t gfp);
+	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(struct wl_priv *wl,
@@ -390,8 +390,6 @@ static __used u32 wl_find_msb(u16 bit16);
 static __used s32 wl_update_pmklist(struct net_device *dev,
 	struct wl_pmk_list *pmk_list, s32 err);
 
-static void wl_set_mpc(struct net_device *ndev, s32 mpc);
-
 /*
  * debufs support
  */
@@ -820,14 +818,14 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
 		return NULL;
 	}
 
-	if (test_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status) == 1) {
+	if (wl_get_p2p_status(wl, IF_DELETING) == 1) {
 		/* wait till IF_DEL is complete
 		 * release the lock for the unregister to proceed
 		 */
 		rtnl_unlock();
 		WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n", __func__));
 		timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
-			(test_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status) == FALSE),
+			(wl_get_p2p_status(wl, IF_DELETING) == FALSE),
 			msecs_to_jiffies(MAX_WAIT_TIME));
 
 		/* put back the rtnl_lock again */
@@ -840,14 +838,14 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
 			return ERR_PTR(-EAGAIN);
 		}
 	}
-	if (!wl->p2p_on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
-		wl->p2p_on = true;
+	if (!p2p_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
+		p2p_on(wl) = true;
 		wl_cfgp2p_init_discovery(wl);
 	}
 
-	memset(wl->p2p_vir_ifname, 0, IFNAMSIZ);
-	strncpy(wl->p2p_vir_ifname, name, IFNAMSIZ - 1);
-	wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+	memset(wl->p2p.vir_ifname, 0, IFNAMSIZ);
+	strncpy(wl->p2p.vir_ifname, name, IFNAMSIZ - 1);
+	wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p.dev_addr, &wl->p2p.int_addr);
 
 	/* Temporary use channel 11, in case GO will be changed with set_channel API  */
 	chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
@@ -855,16 +853,16 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
 	/* For P2P mode, use P2P-specific driver features to create the
 	 * bss: "wl p2p_ifadd"
 	 */
-	set_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
-	err = wl_cfgp2p_ifadd(wl, &wl->p2p_int_addr, htod32(wlif_type), chspec);
+	wl_set_p2p_status(wl, IF_ADD);
+	err = wl_cfgp2p_ifadd(wl, &wl->p2p.int_addr, htod32(wlif_type), chspec);
 
 	if (unlikely(err))
 		return ERR_PTR(-ENOMEM);
 
 	timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
-		(test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status) == FALSE),
+		(wl_get_p2p_status(wl, IF_ADD) == FALSE),
 		msecs_to_jiffies(MAX_WAIT_TIME));
-	if (timeout > 0 && (!test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status))) {
+	if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
 
 		struct wireless_dev *vwdev;
 		vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
@@ -873,7 +871,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
 			return ERR_PTR(-ENOMEM);
 		}
 		vwdev->wiphy = wl->wdev->wiphy;
-		WL_INFO((" virtual interface(%s) is created \n", wl->p2p_vir_ifname));
+		WL_INFO((" virtual interface(%s) is created \n", wl->p2p.vir_ifname));
 		index = alloc_idx_vwdev(wl);
 		wl->vwdev[index] = vwdev;
 		vwdev->iftype =
@@ -884,16 +882,16 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
 		SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
 		vwdev->netdev = _ndev;
 		set_bit(WL_STATUS_READY, &wl->status);
-		wl->p2p_vif_created = TRUE;
+		wl->p2p.vif_created = TRUE;
 		set_mode_by_netdev(wl, _ndev, mode);
 		wl = wdev_to_wl(vwdev);
 		return _ndev;
 
 	} else {
-		clear_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
-		WL_ERR((" virtual interface(%s) is not created \n", wl->p2p_vir_ifname));
-		memset(wl->p2p_vir_ifname, '\0', IFNAMSIZ);
-		wl->p2p_vif_created = FALSE;
+		wl_clr_p2p_status(wl, IF_ADD);
+		WL_ERR((" virtual interface(%s) is not created \n", wl->p2p.vir_ifname));
+		memset(wl->p2p.vir_ifname, '\0', IFNAMSIZ);
+		wl->p2p.vif_created = FALSE;
 	}
 
 	return ERR_PTR(-ENODEV);
@@ -905,15 +903,15 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
 {
 	struct ether_addr p2p_mac;
 	struct wl_priv *wl = WL_PRIV_GET();
-	memcpy(p2p_mac.octet, wl->p2p_int_addr.octet, ETHER_ADDR_LEN);
-	if (wl->p2p_vif_created) {
+	memcpy(p2p_mac.octet, wl->p2p.int_addr.octet, ETHER_ADDR_LEN);
+	if (wl->p2p.vif_created) {
 		if (test_bit(WL_STATUS_SCANNING, &wl->status)) {
 			wl_cfg80211_scan_abort(wl, dev);
 		}
 		wl_cfgp2p_ifdel(wl, &p2p_mac);
 		WL_ERR(("ifdel command sent to Firmware.. "
 				"and we just come out without waiting.."));
-		set_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status);
+		wl_set_p2p_status(wl, IF_DELETING);
 
 	}
 
@@ -962,21 +960,21 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
 	}
 
 
-	if (ap && wl->p2p_vif_created) {
-		WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p_vif_created,
-			wl->p2p_on));
+	if (ap && wl->p2p.vif_created) {
+		WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p.vif_created,
+			p2p_on(wl)));
 		chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
 		wlif_type = ap ? WL_P2P_IF_GO : WL_P2P_IF_CLIENT;
 		WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n", ndev->name, ap, infra, type));
-		set_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status);
-		clear_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status);
-		err = wl_cfgp2p_ifchange(wl, &wl->p2p_int_addr, htod32(wlif_type), chspec);
+		wl_set_p2p_status(wl, IF_CHANGING);
+		wl_clr_p2p_status(wl, IF_CHANGED);
+		err = wl_cfgp2p_ifchange(wl, &wl->p2p.int_addr, htod32(wlif_type), chspec);
 		timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
-			(test_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status) == TRUE),
+			(wl_get_p2p_status(wl, IF_CHANGED) == TRUE),
 			msecs_to_jiffies(MAX_WAIT_TIME));
 		set_mode_by_netdev(wl, ndev, mode);
-		clear_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status);
-		clear_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status);
+		wl_clr_p2p_status(wl, IF_CHANGING);
+		wl_clr_p2p_status(wl, IF_CHANGED);
 	}
 
 	ndev->ieee80211_ptr->iftype = type;
@@ -994,12 +992,12 @@ wl_cfg80211_notify_ifadd(struct net_device *net)
 	}
 
 	WL_DBG(("IF_ADD event called from dongle, old interface name: %s, new name: %s\n",
-		net->name, wl->p2p_vir_ifname));
+		net->name, wl->p2p.vir_ifname));
 	/* Assign the net device to CONNECT BSSCFG */
-	strncpy(net->name, wl->p2p_vir_ifname, IFNAMSIZ - 1);
+	strncpy(net->name, wl->p2p.vir_ifname, IFNAMSIZ - 1);
 	wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
 	wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = P2PAPI_BSSCFG_CONNECTION;
-	clear_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
+	wl_clr_p2p_status(wl, IF_ADD);
 	wake_up_interruptible(&wl->dongle_event_wait);
 	return ret;
 }
@@ -1015,14 +1013,14 @@ wl_cfg80211_notify_ifdel(struct net_device *net)
 	}
 
 	WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
-		net->name, wl->p2p_vir_ifname));
-	if (wl->p2p_vif_created) {
+		net->name, wl->p2p.vir_ifname));
+	if (wl->p2p.vif_created) {
 		s32 index = 0;
-		memset(wl->p2p_vir_ifname, '\0', IFNAMSIZ);
+		memset(wl->p2p.vir_ifname, '\0', IFNAMSIZ);
 		index = wl_cfgp2p_find_idx(wl, net);
 		wl_to_p2p_bss_ndev(wl, index) = NULL;
 		wl_to_p2p_bss_bssidx(wl, index) = 0;
-		wl->p2p_vif_created = FALSE;
+		wl->p2p.vif_created = FALSE;
 		set_mode_by_netdev(wl, net, -1);
 		wl_cfgp2p_clear_management_ie(wl,
 			index);
@@ -1032,7 +1030,7 @@ wl_cfg80211_notify_ifdel(struct net_device *net)
 				free_vwdev_by_index(wl, index);
 		}
 		/* Another option.. Make the IF_ADD wait, if the IF_DEL is not complete.. */
-		clear_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status);
+		wl_clr_p2p_status(wl, IF_DELETING);
 		WL_ERR(("Cleared IF_DELETING status bit\n"));
 		wake_up_interruptible(&wl->dongle_event_wait);
 		WL_ERR(("Cleared IF_DELETING status bit DONE WAKEUP Interruptible\n"));
@@ -1045,7 +1043,7 @@ wl_cfg80211_is_progress_ifadd(void)
 {
 	s32 is_progress = 0;
 	struct wl_priv *wl = WL_PRIV_GET();
-	if (test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status))
+	if (wl_get_p2p_status(wl, IF_ADD))
 		is_progress = 1;
 	return is_progress;
 }
@@ -1055,7 +1053,7 @@ wl_cfg80211_is_progress_ifchange(void)
 {
 	s32 is_progress = 0;
 	struct wl_priv *wl = WL_PRIV_GET();
-	if (test_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status))
+	if (wl_get_p2p_status(wl, IF_CHANGING))
 		is_progress = 1;
 	return is_progress;
 }
@@ -1065,8 +1063,8 @@ s32
 wl_cfg80211_notify_ifchange(void)
 {
 	struct wl_priv *wl = WL_PRIV_GET();
-	if (test_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status)) {
-		set_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status);
+	if (wl_get_p2p_status(wl, IF_CHANGING)) {
+		wl_set_p2p_status(wl, IF_CHANGED);
 		wake_up_interruptible(&wl->dongle_event_wait);
 	}
 	return 0;
@@ -1148,7 +1146,6 @@ static s32 wl_do_iscan(struct wl_priv *wl)
 		WL_DBG(("error (%d)\n", err));
 		return err;
 	}
-	wl_set_mpc(ndev, 0);
 	wl->iscan_kickstart = true;
 	wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
 	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
@@ -1172,7 +1169,7 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint
 
 
 	if ((ndev == wl_to_prmry_ndev(wl)) &&
-		!wl->p2p_scan) {
+		!p2p_scan(wl)) {
 		/* LEGACY SCAN TRIGGER */
 		WL_DBG(("LEGACY SCAN START\n"));
 		if (ssid && ssid->SSID_len) {
@@ -1203,7 +1200,7 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint
 			wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
 		kfree(params);
 	}
-	else if (wl->p2p_on && wl->p2p_scan) {
+	else if (p2p_on(wl) && p2p_scan(wl)) {
 		/* P2P SCAN TRIGGER */
 		if (scan_request && scan_request->n_channels) {
 			num_chans = scan_request->n_channels;
@@ -1246,8 +1243,6 @@ exit:
 static s32
 wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wlc_ssid_t *ssid)
 {
-
-
 	s32 err = BCME_OK;
 	s32 passive_scan;
 	wl_scan_results_t *results;
@@ -1267,7 +1262,6 @@ wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wl
 	results->count = 0;
 	results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
 
-	wl_set_mpc(ndev, 0);
 	wl_run_escan(wl, ndev, ssid, WL_SCAN_ACTION_START);
 	return err;
 }
@@ -1309,27 +1303,27 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 			escan_req = true;
 			if (ssids->ssid_len && IS_P2P_SSID(ssids->ssid)) {
 				/* p2p scan trigger */
-				if (wl->p2p_on == false) {
+				if (p2p_on(wl) == false) {
 					/* p2p on at the first time */
-					wl->p2p_on = true;
+					p2p_on(wl) = true;
 					wl_cfgp2p_set_firm_p2p(wl);
 				}
 
-				wl->p2p_scan = true;
+				p2p_scan(wl) = true;
 
 			} else {
 				/* legacy scan trigger
 				 * So, we have to disable p2p discovery if p2p discovery is on
 				 */
-				wl->p2p_scan = false;
+				p2p_scan(wl) = false;
 				/* If Netdevice is not equals to primary and p2p is on
 				*  , we will do p2p scan using P2PAPI_BSSCFG_DEVICE.
 							 */
-				if (wl->p2p_on && (ndev != wl_to_prmry_ndev(wl)))
-					wl->p2p_scan = true;
+				if (p2p_on(wl) && (ndev != wl_to_prmry_ndev(wl)))
+					p2p_scan(wl) = true;
 
-				if (wl->p2p_scan == false) {
-					if (test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status)) {
+				if (p2p_scan(wl) == false) {
+					if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
 						err = wl_cfgp2p_discover_enable_search(wl, FALSE);
 						if (unlikely(err)) {
 							goto scan_out;
@@ -1358,7 +1352,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 		memcpy(ssid_info.SSID, ssids->ssid, ssids->ssid_len);
 		ssid_info.SSID_len = ssids->ssid_len;
 
-		if (wl->p2p_on && wl->p2p_scan) {
+		if (p2p_on(wl) && p2p_scan(wl)) {
 
 			err = wl_cfgp2p_enable_discovery(wl, ndev, request->ie, request->ie_len);
 
@@ -1394,7 +1388,6 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 			WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
 			goto scan_out;
 		}
-		wl_set_mpc(ndev, 0);
 		err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
 			sizeof(sr->ssid), FALSE);
 		if (err) {
@@ -1404,7 +1397,6 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 			} else {
 				WL_ERR(("WLC_SCAN error (%d)\n", err));
 			}
-			wl_set_mpc(ndev, 1);
 			goto scan_out;
 		}
 	}
@@ -1914,7 +1906,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	CHECK_SYS_UP();
 	if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
 		/* we only allow to connect using virtual interface in case of P2P */
-		if (wl->p2p_on && is_wps_conn(sme)) {
+		if (p2p_on(wl) && is_wps_conn(sme)) {
 			WL_DBG(("p2p index : %d\n", wl_cfgp2p_find_idx(wl, dev)));
 			/* Have to apply WPS IE + P2P IE in assoc req frame */
 			wl_cfgp2p_set_managment_ie(wl, dev,
@@ -1924,7 +1916,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 				P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
 			wl_cfgp2p_set_managment_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
 				VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
-		} else if (wl->p2p_on && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
+		} else if (p2p_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
 			/* This is the connect req after WPS is done [credentials exchanged] 
 			 * currently identified with WPA_VERSION_2 .
 			 * Update the previously set IEs with
@@ -2610,7 +2602,6 @@ static s32 wl_cfg80211_resume(struct wiphy *wiphy)
 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
 {
 	struct wl_priv *wl = WL_PRIV_GET();
-	struct net_device *ndev = wl_to_prmry_ndev(wl);
 	s32 err = 0;
 
 	CHECK_SYS_UP();
@@ -2619,7 +2610,6 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
 	wl_term_iscan(wl);
 	if (wl->scan_request) {
 		cfg80211_scan_done(wl->scan_request, true);
-		wl_set_mpc(ndev, 1);
 		wl->scan_request = NULL;
 	}
 	clear_bit(WL_STATUS_SCANNING, &wl->status);
@@ -2811,7 +2801,7 @@ wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
 		wl_event_msg_t msg;
 		msg.event_type =  hton32(WLC_E_ESCAN_RESULT);
 		msg.status = WLC_E_STATUS_ABORT;
-		wl_cfg80211_event(ndev, &msg, NULL, GFP_ATOMIC);
+		wl_cfg80211_event(ndev, &msg, NULL);
 	}
 	return err;
 }
@@ -2837,8 +2827,8 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
 	wl->cache_cookie = *cookie;
 	cfg80211_ready_on_channel(dev, *cookie, channel,
 		channel_type, duration, GFP_KERNEL);
-	if (!wl->p2p_on) {
-		wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+	if (!p2p_on(wl)) {
+		wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p.dev_addr, &wl->p2p.int_addr);
 
 		/* In case of p2p_listen command, supplicant send remain_on_channel
 		 * without turning on P2P
@@ -2849,9 +2839,9 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
 		if (unlikely(err)) {
 			goto exit;
 		}
-		wl->p2p_on = true;
+		p2p_on(wl) = true;
 	}
-	if (wl->p2p_on)
+	if (p2p_on(wl))
 		wl_cfgp2p_discover_listen(wl, target_channel, duration);
 
 
@@ -2901,8 +2891,8 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 		WL_ERR(("Can not find the bssidx for dev( %p )\n", dev));
 		return -ENODEV;
 	}
-	if (wl->p2p_on) {
-		wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+	if (p2p_on(wl)) {
+		wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p.dev_addr, &wl->p2p.int_addr);
 
 	   /* Suspend P2P discovery search-listen to prevent it from changing the
 		* channel.
@@ -2919,7 +2909,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 	mgmt = (const struct ieee80211_mgmt *) buf;
 	fc = mgmt->frame_control;
 	if (fc != IEEE80211_STYPE_ACTION) {
-		if (wl->p2p_on && (fc == IEEE80211_STYPE_PROBE_RESP)) {
+		if (p2p_on(wl) && (fc == IEEE80211_STYPE_PROBE_RESP)) {
 			s32 ie_offset =  DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
 			s32 ie_len = len - ie_offset;
 			if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)(buf + ie_offset), ie_len))
@@ -2986,7 +2976,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 
 	memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
 
-	if (wl->p2p_vif_created) {
+	if (wl->p2p.vif_created) {
 		wifi_p2p_pub_act_frame_t *act_frm =
 			(wifi_p2p_pub_act_frame_t *) (action_frame->data);
 		/*
@@ -3000,11 +2990,11 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 			p2p_ie = wl_cfgp2p_find_p2pie(act_frm->elts,
 				action_frame->len - P2P_PUB_AF_FIXED_LEN);
 		#ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
-			wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_int_addr,
+			wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.int_addr,
 				P2P_SEID_INTINTADDR);
-			wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr,
+			wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
 				P2P_SEID_DEV_INFO);
-			wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr,
+			wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
 				P2P_SEID_GROUP_ID);
 		#endif
 		}
@@ -3209,11 +3199,8 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
 	WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
 		info->interval, info->dtim_period, info->head_len, info->tail_len));
 
-	/*
-	 * !!! The following code was NOT indented properly, PLEASE merge your code
-	 * to SVN verion becuase your merger tool may IGNORE tabs/spaces
-	 */
-	if (wl->p2p_on && (bssidx >= wl_to_p2p_bss_bssidx(wl,
+
+	if (p2p_on(wl) && (bssidx >= wl_to_p2p_bss_bssidx(wl,
 		P2PAPI_BSSCFG_CONNECTION))) {
 		/* We don't need to set beacon for P2P_GO,
 		 * but need to parse ssid from beacon_parameters
@@ -3224,8 +3211,8 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
 		if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
 			info->head_len - ie_offset,
 			DOT11_MNG_SSID_ID)) != NULL) {
-			memcpy(wl->p2p_ssid.SSID, ssid_ie->data, ssid_ie->len);
-			wl->p2p_ssid.SSID_len = ssid_ie->len;
+			memcpy(wl->p2p.ssid.SSID, ssid_ie->data, ssid_ie->len);
+			wl->p2p.ssid.SSID_len = ssid_ie->len;
 			WL_DBG(("SSID (%s) in Head \n", ssid_ie->data));
 
 		} else {
@@ -3285,8 +3272,8 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
 				WL_ERR(("SET INFRA error %d\n", err));
 			}
 
-			err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p_ssid,
-				sizeof(wl->p2p_ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
+			err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p.ssid,
+				sizeof(wl->p2p.ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
 
 			wl_cfgp2p_bss(dev, bssidx, 1);
 		}
@@ -3535,7 +3522,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
 		offsetof(struct wl_cfg80211_bss_info, frame_buf));
 	notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
 		u.beacon.variable) + wl_get_ielen(wl);
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
 	freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
 #else
 	freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
@@ -3665,7 +3652,7 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
 		else
 			band = wiphy->bands[IEEE80211_BAND_5GHZ];
 
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
 		freq = ieee80211_channel_to_frequency(channel);
 #else
 		freq = ieee80211_channel_to_frequency(channel, band->band);
@@ -4071,7 +4058,6 @@ scan_done_out:
 	if (wl->scan_request) {
 		WL_ERR(("cfg80211_scan_done\n"));
 		cfg80211_scan_done(wl->scan_request, false);
-		wl_set_mpc(ndev, 1);
 		wl->scan_request = NULL;
 	}
 	rtnl_unlock();
@@ -4140,8 +4126,7 @@ wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
 	else
 		band = wiphy->bands[IEEE80211_BAND_5GHZ];
-
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
 	freq = ieee80211_channel_to_frequency(channel);
 #else
 	freq = ieee80211_channel_to_frequency(channel, band->band);
@@ -4350,7 +4335,6 @@ static void wl_term_iscan(struct wl_priv *wl)
 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
 {
 	struct wl_priv *wl = iscan_to_wl(iscan);
-	struct net_device *ndev = wl_to_prmry_ndev(wl);
 
 	WL_DBG(("Enter \n"));
 	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
@@ -4359,7 +4343,6 @@ static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
 	}
 	if (likely(wl->scan_request)) {
 		cfg80211_scan_done(wl->scan_request, aborted);
-		wl_set_mpc(ndev, 1);
 		wl->scan_request = NULL;
 	}
 	wl->iscan_kickstart = false;
@@ -4546,19 +4529,16 @@ static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan)
 
 static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
 {
-
-	struct net_device *ndev = wl_to_prmry_ndev(wl);
 	WL_DBG(("Enter \n"));
 	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
 		WL_ERR(("Scan complete while device not scanning\n"));
 		return;
 	}
-	if (wl->p2p_on)
-	   clear_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status);
+	if (p2p_on(wl))
+	   wl_clr_p2p_status(wl, SCANNING);
 
 	if (likely(wl->scan_request)) {
 		cfg80211_scan_done(wl->scan_request, aborted);
-		wl_set_mpc(ndev, 1);
 		wl->scan_request = NULL;
 	}
 }
@@ -4751,10 +4731,10 @@ s32 wl_cfg80211_sysctl_export_devaddr(void *data)
 	dhd_pub_t *dhd = (dhd_pub_t *)data;
 	struct wl_priv *wl = WL_PRIV_GET();
 
-	wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+	wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p.dev_addr, &wl->p2p.int_addr);
 
-	sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p_dev_addr.octet));
-	sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p_int_addr.octet));
+	sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p.dev_addr.octet));
+	sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p.int_addr.octet));
 
 	return 0;
 }
@@ -4772,7 +4752,7 @@ s32 wl_cfg80211_attach_post(struct net_device *ndev)
 	wl = WL_PRIV_GET();
 	if (wl && !test_bit(WL_STATUS_READY, &wl->status)) {
 			if (wl->wdev &&
-				wl_cfgp2p_is_p2p_supported(wl, ndev)) {
+				wl_cfgp2p_supported(wl, ndev)) {
 				WL_INFO(("P2P is supported on Firmware \n"));
 				wl->wdev->wiphy->interface_modes |=
 					(BIT(NL80211_IFTYPE_P2P_CLIENT)|
@@ -4905,7 +4885,7 @@ static s32 wl_event_handler(void *data)
 }
 
 void
-wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data, gfp_t gfp)
+wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
 {
 	u32 event_type = ntoh32(e->event_type);
 	struct wl_priv *wl = WL_PRIV_GET();
@@ -4916,7 +4896,7 @@ wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data,
 	WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
 #endif /* (WL_DBG_LEVEL > 0) */
 
-	if (likely(!wl_enq_event(wl, ndev, event_type, e, data, gfp)))
+	if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
 		wl_wakeup_event(wl);
 }
 
@@ -4963,7 +4943,7 @@ static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
 
 static s32
 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg,
-	void *data, gfp_t gfp)
+	void *data)
 {
 	struct wl_event_q *e;
 	s32 err = 0;
@@ -4974,7 +4954,7 @@ wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_ev
 	if (data)
 		data_len = ntoh32(msg->datalen);
 	evtq_size = sizeof(struct wl_event_q) + data_len;
-	e = kzalloc(evtq_size, gfp);
+	e = kzalloc(evtq_size, GFP_ATOMIC);
 	if (unlikely(!e)) {
 		WL_ERR(("event alloc failed\n"));
 		return -ENOMEM;
@@ -5485,12 +5465,6 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
 	if (wl->scan_request) {
 		cfg80211_scan_done(wl->scan_request, true);
 
-		/* BUG: this operation cannot help but here because sdio
-		 * is already down through rmmod process. Need to figure
-		 * out how to address this issue
-		 */
-		/* wl_set_mpc(wl_to_ndev(wl), 1); */
-
 		wl->scan_request = NULL;
 	}
 	clear_bit(WL_STATUS_READY, &wl->status);
@@ -5830,21 +5804,6 @@ s8 *wl_cfg80211_get_nvramname(void)
 	return wl->fw->nvram_name;
 }
 
-static void wl_set_mpc(struct net_device *ndev, s32 mpc)
-{
-
-	s32 err = 0;
-
-	WL_TRACE(("In\n"));
-	err = wl_dev_intvar_set(ndev, "mpc", mpc);
-	if (unlikely(err)) {
-		WL_ERR(("fail to set mpc\n"));
-		return;
-	}
-	WL_DBG(("MPC : %d\n", mpc));
-
-}
-
 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
 {
 	char buf[10+IFNAMSIZ];
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 4ec91e8..4c05987 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -35,12 +35,15 @@
 #include <net/cfg80211.h>
 #include <linux/rfkill.h>
 
+#include <wl_cfgp2p.h>
+
 struct wl_conf;
 struct wl_iface;
 struct wl_priv;
 struct wl_security;
 struct wl_ibss;
 
+
 #define htod32(i) i
 #define htod16(i) i
 #define dtoh32(i) i
@@ -164,19 +167,6 @@ enum wl_fw_status {
 	WL_NVRAM_LOADING_DONE
 };
 
-/* dongle status */
-enum wl_cfgp2p_status {
-	WLP2P_STATUS_DISCOVERY_ON,
-	WLP2P_STATUS_SEARCH_ENABLED,
-	WLP2P_STATUS_IF_ADD,
-	WLP2P_STATUS_IF_DEL,
-	WLP2P_STATUS_IF_DELETING,
-	WLP2P_STATUS_IF_CHANGING,
-	WLP2P_STATUS_IF_CHANGED,
-	WLP2P_STATUS_LISTEN_EXPIRED,
-	WLP2P_STATUS_ACTION_TX_COMPLETED,
-	WLP2P_STATUS_SCANNING
-};
 /* beacon / probe_response */
 struct beacon_proberesp {
 	__le64 timestamp;
@@ -315,37 +305,7 @@ struct wl_pmk_list {
 	pmkid_list_t pmkids;
 	pmkid_t foo[MAXPMKID - 1];
 };
-/* Enumeration of the usages of the BSSCFGs used by the P2P Library.  Do not
- * confuse this with a bsscfg index.  This value is an index into the
- * saved_ie[] array of structures which in turn contains a bsscfg index field.
- */
-typedef enum {
-	P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
-	P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
-	P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
-	P2PAPI_BSSCFG_MAX
-} p2p_bsscfg_type_t;
-
-#define IE_MAX_LEN 300
-/* Structure to hold all saved P2P and WPS IEs for a BSSCFG */
-typedef struct p2p_saved_ie_s {
-	u8  p2p_probe_req_ie[IE_MAX_LEN];
-	u32 p2p_probe_req_ie_len;
-	u8  p2p_probe_res_ie[IE_MAX_LEN];
-	u32 p2p_probe_res_ie_len;
-	u8  p2p_assoc_req_ie[IE_MAX_LEN];
-	u32 p2p_assoc_req_ie_len;
-	u8  p2p_assoc_res_ie[IE_MAX_LEN];
-	u32 p2p_assoc_res_ie_len;
-	u8  p2p_beacon_ie[IE_MAX_LEN];
-	u32 p2p_beacon_ie_len;
-} p2p_saved_ie_t;
-
-struct p2p_bss {
-    u32 bssidx;
-    struct net_device *dev;
-	p2p_saved_ie_t saved_ie;
-};
+
 
 #define ESCAN_BUF_SIZE (64 * 1024)
 
@@ -417,19 +377,9 @@ struct wl_priv {
 	struct ieee80211_channel remain_on_chan;
 	enum nl80211_channel_type remain_on_chan_type;
 	u64 cache_cookie;
-    wait_queue_head_t dongle_event_wait;
-	struct timer_list *listen_timer;
+	wait_queue_head_t dongle_event_wait;
+	struct p2p_info p2p;
 	s8 last_eventmask[WL_EVENTING_MASK_LEN];
-	bool p2p_on;    /* p2p on/off switch */
-	bool p2p_scan;
-	bool p2p_vif_created;
-	s8 p2p_vir_ifname[IFNAMSIZ];
-	unsigned long p2p_status;
-	struct ether_addr p2p_dev_addr;
-	struct ether_addr p2p_int_addr;
-	struct p2p_bss p2p_bss_idx[P2PAPI_BSSCFG_MAX];
-	wlc_ssid_t p2p_ssid;
-	s32 sta_generation;
 	u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
 };
 
@@ -448,10 +398,7 @@ struct wl_priv {
 #define wl_to_iscan(w) (w->iscan)
 #define wl_to_conn(w) (&w->conn_info)
 #define wiphy_from_scan(w) (w->escan_info.wiphy)
-#define wl_to_p2p_bss_ndev(w, type) 	(wl->p2p_bss_idx[type].dev)
-#define wl_to_p2p_bss_bssidx(w, type) 	(wl->p2p_bss_idx[type].bssidx)
-#define wl_to_p2p_bss_saved_ie(w, type) 	(wl->p2p_bss_idx[type].saved_ie)
-#define wl_to_p2p_bss(w, type) (wl->p2p_bss_idx[type])
+
 static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
 {
 	return bss = bss ?
@@ -535,7 +482,7 @@ extern s32 wl_cfg80211_attach_post(struct net_device *ndev);
 extern void wl_cfg80211_detach(void);
 /* event handler from dongle */
 extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e,
-            void *data, gfp_t gfp);
+            void *data);
 extern void wl_cfg80211_set_sdio_func(void *func);	/* set sdio function info */
 extern struct sdio_func *wl_cfg80211_get_sdio_func(void);	/* set sdio function info */
 extern s32 wl_cfg80211_up(void);	/* dongle up */
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index 730a25f..e2780df 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -51,49 +51,6 @@
 #include <wldev_common.h>
 
 
-/* dword align allocation */
-#define WLC_IOCTL_MAXLEN 8192
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
-
-#define CFGP2P_DBG_NONE	0
-#define CFGP2P_DBG_DBG 	(1 << 2)
-#define CFGP2P_DBG_INFO	(1 << 1)
-#define CFGP2P_DBG_ERR	(1 << 0)
-#define CFGP2P_DBG_MASK ((WL_DBG_DBG | WL_DBG_INFO | WL_DBG_ERR) << 1)
-
-
-#define CFGP2P_DBG_LEVEL 0xFF		/* 0 invalidates all debug messages */
-
-u32 cfgp2p_dbg_level = CFGP2P_DBG_ERR | CFGP2P_DBG_INFO | CFGP2P_DBG_DBG;
-
-#define CFGP2P_ERR(args)									\
-	do {										\
-		if (cfgp2p_dbg_level & CFGP2P_DBG_ERR) {				\
-			printk(KERN_ERR "CFGP2P-ERROR) %s : ", __func__);	\
-			printk args;						\
-		}									\
-	} while (0)
-#define	CFGP2P_INFO(args)									\
-	do {										\
-		if (cfgp2p_dbg_level & CFGP2P_DBG_INFO) {				\
-			printk(KERN_ERR "CFGP2P-INFO) %s : ", __func__);	\
-			printk args;						\
-		}									\
-	} while (0)
-#if (CFGP2P_DBG_LEVEL > 0)
-#define	CFGP2P_DBG(args)								\
-	do {									\
-		if (cfgp2p_dbg_level & CFGP2P_DBG_DBG) {			\
-			printk(KERN_ERR "CFGP2P-DEBUG) %s :", __func__);	\
-			printk args;							\
-		}									\
-	} while (0)
-#else				/* !(WL_DBG_LEVEL > 0) */
-#define	CFGP2P_DBG(args)
-#endif				/* (WL_DBG_LEVEL > 0) */
-
-
 static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
 static s8 scanparambuf[WLC_IOCTL_SMLEN];
 static s8 *smbuf = ioctlbuf;
@@ -111,10 +68,10 @@ wl_cfgp2p_vndr_ie(struct net_device *ndev, s32 bssidx, s32 pktflag,
 void
 wl_cfgp2p_init_priv(struct wl_priv *wl)
 {
-	wl->p2p_on = 0;
-	wl->p2p_scan = 0; /* by default , legacy scan */
-	wl->p2p_status = 0;
-	wl->listen_timer = NULL;
+	wl->p2p.on = 0;
+	wl->p2p.scan = 0; /* by default , legacy scan */
+	wl->p2p.status = 0;
+	wl->p2p.listen_timer = NULL;
 
 #define INIT_IE(IE_TYPE, BSS_TYPE)		\
 	do {							\
@@ -435,12 +392,12 @@ s32
 wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8 *ie, u32 ie_len)
 {
 	s32 ret = BCME_OK;
-	if (test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status)) {
+	if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
 		CFGP2P_INFO((" DISCOVERY is already initialized, we have nothing to do\n"));
 		goto set_ie;
 	}
 
-	set_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status);
+	wl_set_p2p_status(wl, DISCOVERY_ON);
 
 	CFGP2P_DBG(("enter\n"));
 
@@ -481,7 +438,7 @@ wl_cfgp2p_disable_discovery(struct wl_priv *wl)
 {
 	s32 ret = BCME_OK;
 	CFGP2P_DBG((" enter\n"));
-	clear_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status);
+	wl_clr_p2p_status(wl, DISCOVERY_ON);
 
 	if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) {
 		CFGP2P_ERR((" do nothing, not initialized\n"));
@@ -499,11 +456,11 @@ wl_cfgp2p_disable_discovery(struct wl_priv *wl)
 	 * waiting out an action frame tx dwell time.
 	 */
 #ifdef NOT_YET
-	if (test_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status)) {
+	if (wl_get_p2p_status(wl, SCANNING)) {
 		p2pwlu_scan_abort(hdl, FALSE);
 	}
 #endif
-	clear_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status);
+	wl_clr_p2p_status(wl, DISCOVERY_ON);
 	ret = wl_cfgp2p_deinit_discovery(wl);
 
 exit:
@@ -528,7 +485,7 @@ wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
 #define P2PAPI_SCAN_DWELL_TIME_MS 40
 #define P2PAPI_SCAN_HOME_TIME_MS 10
 
-	set_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status);
+	wl_set_p2p_status(wl, SCANNING);
 	/* Allocate scan params which need space for 3 channels and 0 ssids */
 	eparams_size = (WL_SCAN_PARAMS_FIXED_SIZE +
 	    OFFSETOF(wl_escan_params_t, params)) +
@@ -918,11 +875,11 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
 
 	CFGP2P_DBG((" Enter\n"));
 	/* TODO : have to acquire bottom half lock ? */
-	if (test_bit(WLP2P_STATUS_LISTEN_EXPIRED, &wl->p2p_status) == 0) {
-		set_bit(WLP2P_STATUS_LISTEN_EXPIRED, &wl->p2p_status);
+	if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) {
+		wl_set_p2p_status(wl, LISTEN_EXPIRED);
 
-		if (wl->listen_timer)
-			del_timer_sync(wl->listen_timer);
+		if (wl->p2p.listen_timer)
+			del_timer_sync(wl->p2p.listen_timer);
 
 		cfg80211_remain_on_channel_expired(ndev, wl->cache_cookie, &wl->remain_on_chan,
 		    wl->remain_on_chan_type, GFP_KERNEL);
@@ -945,7 +902,7 @@ wl_cfgp2p_listen_expired(unsigned long data)
 
 	CFGP2P_DBG((" Enter\n"));
 	msg.event_type =  hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE);
-	wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL, GFP_ATOMIC);
+	wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL);
 }
 
 /* 
@@ -974,7 +931,7 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
 	s32 ret = BCME_OK;
 	CFGP2P_DBG((" Enter\n"));
 	CFGP2P_INFO(("Channel : %d, Duration : %d\n", channel, duration_ms));
-	if (unlikely(test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status) == 0)) {
+	if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) {
 
 		CFGP2P_ERR((" Discovery is not set, so we have noting to do\n"));
 
@@ -982,17 +939,17 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
 		goto exit;
 	}
 
-	clear_bit(WLP2P_STATUS_LISTEN_EXPIRED, &wl->p2p_status);
+	wl_clr_p2p_status(wl, LISTEN_EXPIRED);
 
 	wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms,
 	            wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
 
-	if (wl->listen_timer)
-		del_timer_sync(wl->listen_timer);
+	if (wl->p2p.listen_timer)
+		del_timer_sync(wl->p2p.listen_timer);
 
-	wl->listen_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
+	wl->p2p.listen_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
 
-	if (wl->listen_timer == NULL) {
+	if (wl->p2p.listen_timer == NULL) {
 		CFGP2P_ERR(("listen_timer allocation failed\n"));
 		return -ENOMEM;
 	}
@@ -1000,7 +957,7 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
 	/*  We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle , 
 	 *  otherwise we will wait up to duration_ms + 10ms
 	 */
-	INIT_TIMER(wl->listen_timer, wl_cfgp2p_listen_expired, duration_ms, 20);
+	INIT_TIMER(wl->p2p.listen_timer, wl_cfgp2p_listen_expired, duration_ms, 20);
 
 #undef INIT_TIMER
 exit:
@@ -1009,26 +966,26 @@ exit:
 
 
 s32
-wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 search_enable)
+wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable)
 {
 	s32 ret = BCME_OK;
 	CFGP2P_DBG((" Enter\n"));
-	if (!test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status)) {
+	if (!wl_get_p2p_status(wl, DISCOVERY_ON)) {
 
 		CFGP2P_ERR((" do nothing, discovery is off\n"));
 		return ret;
 	}
-	if (test_bit(WLP2P_STATUS_SEARCH_ENABLED, &wl->p2p_status) == search_enable) {
-		CFGP2P_ERR(("already : %d\n", search_enable));
+	if (wl_get_p2p_status(wl, SEARCH_ENABLED) == enable) {
+		CFGP2P_ERR(("already : %d\n", enable));
 		return ret;
 	}
 
-	change_bit(WLP2P_STATUS_SEARCH_ENABLED, &wl->p2p_status);
+	wl_chg_p2p_status(wl, SEARCH_ENABLED);
 	/* When disabling Search, reset the WL driver's p2p discovery state to
 	 * WL_P2P_DISC_ST_SCAN.
 	 */
-	if (!search_enable) {
-		clear_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status);
+	if (!enable) {
+		wl_clr_p2p_status(wl, SCANNING);
 		(void) wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
 		            wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
 	}
@@ -1051,7 +1008,7 @@ wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
 
 		CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status));
 		if (status == WLC_E_STATUS_SUCCESS)
-			set_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status);
+			wl_set_p2p_status(wl, ACTION_TX_COMPLETED);
 		else
 			CFGP2P_ERR(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"));
 		wake_up_interruptible(&wl->dongle_event_wait);
@@ -1083,7 +1040,7 @@ wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
 	CFGP2P_INFO(("channel : %u , dwell time : %u\n",
 	    af_params->channel, af_params->dwell_time));
 
-	clear_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status);
+	wl_clr_p2p_status(wl, ACTION_TX_COMPLETED);
 #define MAX_WAIT_TIME 2000
 	if (bssidx == P2PAPI_BSSCFG_PRIMARY)
 		bssidx =  wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
@@ -1097,10 +1054,10 @@ wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
 		goto exit;
 	}
 	timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
-	                (test_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status) == TRUE),
+	                (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) == TRUE),
 	                    msecs_to_jiffies(MAX_WAIT_TIME));
 
-	if (timeout > 0 && test_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status)) {
+	if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) {
 		CFGP2P_INFO(("tx action frame operation is completed\n"));
 		ret = BCME_OK;
 	} else {
@@ -1247,26 +1204,26 @@ wl_cfgp2p_bss(struct net_device *ndev, s32 bsscfg_idx, s32 up)
 
 /* Check if 'p2p' is supported in the driver */
 s32
-wl_cfgp2p_is_p2p_supported(struct wl_priv *wl, struct net_device *ndev)
+wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
 {
 	s32 ret = BCME_OK;
-	s32 is_p2p_supported = 0;
+	s32 p2p_supported = 0;
 	ret = wldev_iovar_getint(ndev, "p2p",
-	               &is_p2p_supported);
+	               &p2p_supported);
 	if (ret < 0) {
 	    CFGP2P_ERR(("wl p2p error %d\n", ret));
 		return 0;
 	}
-	if (is_p2p_supported)
+	if (p2p_supported)
 		CFGP2P_INFO(("p2p is supported\n"));
 
-	return is_p2p_supported;
+	return p2p_supported;
 }
-
+/* Cleanup P2P resources */
 s32
 wl_cfgp2p_down(struct wl_priv *wl)
 {
-	if (wl->listen_timer)
-		del_timer_sync(wl->listen_timer);
+	if (wl->p2p.listen_timer)
+		del_timer_sync(wl->p2p.listen_timer);
 	return 0;
 }
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
index 9fb2c9e..27aef59 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
@@ -28,6 +28,109 @@
 #include <proto/802.11.h>
 #include <proto/p2p.h>
 
+struct wl_priv;
+extern u32 wl_dbg_level;
+
+/* Enumeration of the usages of the BSSCFGs used by the P2P Library.  Do not
+ * confuse this with a bsscfg index.  This value is an index into the
+ * saved_ie[] array of structures which in turn contains a bsscfg index field.
+ */
+typedef enum {
+	P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
+	P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
+	P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
+	P2PAPI_BSSCFG_MAX
+} p2p_bsscfg_type_t;
+
+#define IE_MAX_LEN 300
+/* Structure to hold all saved P2P and WPS IEs for a BSSCFG */
+struct p2p_saved_ie {
+	u8   p2p_probe_req_ie[IE_MAX_LEN];
+	u8   p2p_probe_res_ie[IE_MAX_LEN];
+	u8   p2p_assoc_req_ie[IE_MAX_LEN];
+	u8   p2p_assoc_res_ie[IE_MAX_LEN];
+	u8   p2p_beacon_ie[IE_MAX_LEN];
+	u32 p2p_probe_req_ie_len;
+	u32 p2p_probe_res_ie_len;
+	u32 p2p_assoc_req_ie_len;
+	u32 p2p_assoc_res_ie_len;
+	u32 p2p_beacon_ie_len;
+};
+
+struct p2p_bss {
+	u32 bssidx;
+	struct net_device *dev;
+	struct p2p_saved_ie saved_ie;
+};
+
+struct p2p_info {
+	bool on;    /* p2p on/off switch */
+	bool scan;
+	bool vif_created;
+	s8 vir_ifname[IFNAMSIZ];
+	unsigned long status;
+	struct ether_addr dev_addr;
+	struct ether_addr int_addr;
+	struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
+	struct timer_list *listen_timer;
+	wlc_ssid_t ssid;
+};
+
+/* dongle status */
+enum wl_cfgp2p_status {
+	WLP2P_STATUS_DISCOVERY_ON = 0,
+	WLP2P_STATUS_SEARCH_ENABLED,
+	WLP2P_STATUS_IF_ADD,
+	WLP2P_STATUS_IF_DEL,
+	WLP2P_STATUS_IF_DELETING,
+	WLP2P_STATUS_IF_CHANGING,
+	WLP2P_STATUS_IF_CHANGED,
+	WLP2P_STATUS_LISTEN_EXPIRED,
+	WLP2P_STATUS_ACTION_TX_COMPLETED,
+	WLP2P_STATUS_SCANNING
+};
+
+
+#define wl_to_p2p_bss_ndev(w, type) 	((wl)->p2p.bss_idx[type].dev)
+#define wl_to_p2p_bss_bssidx(w, type) 	((wl)->p2p.bss_idx[type].bssidx)
+#define wl_to_p2p_bss_saved_ie(w, type) 	((wl)->p2p.bss_idx[type].saved_ie)
+#define wl_to_p2p_bss(wl, type) ((wl)->p2p.bss_idx[type])
+#define wl_get_p2p_status(wl, stat)   (test_bit(WLP2P_STATUS_ ## stat, &(wl)->p2p.status))
+#define wl_set_p2p_status(wl, stat)   (set_bit(WLP2P_STATUS_ ## stat, &(wl)->p2p.status))
+#define wl_clr_p2p_status(wl, stat)   (clear_bit(WLP2P_STATUS_ ## stat, &(wl)->p2p.status))
+#define wl_chg_p2p_status(wl, stat)   (change_bit(WLP2P_STATUS_ ## stat, &(wl)->p2p.status))
+#define p2p_on(wl) ((wl)->p2p.on)
+#define p2p_scan(wl) ((wl)->p2p.scan)
+
+
+/* dword align allocation */
+#define WLC_IOCTL_MAXLEN 8192
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+#define CFGP2P_ERR(args)									\
+	do {										\
+		if (wl_dbg_level & WL_DBG_ERR) {				\
+			printk(KERN_ERR "CFGP2P-ERROR) %s : ", __func__);	\
+			printk args;						\
+		}									\
+	} while (0)
+#define	CFGP2P_INFO(args)									\
+	do {										\
+		if (wl_dbg_level & WL_DBG_INFO) {				\
+			printk(KERN_ERR "CFGP2P-INFO) %s : ", __func__);	\
+			printk args;						\
+		}									\
+	} while (0)
+#define	CFGP2P_DBG(args)								\
+	do {									\
+		if (wl_dbg_level & WL_DBG_DBG) {			\
+			printk(KERN_ERR "CFGP2P-DEBUG) %s :", __func__);	\
+			printk args;							\
+		}									\
+	} while (0)
+
+
 extern void
 wl_cfgp2p_init_priv(struct wl_priv *wl);
 extern s32
@@ -83,7 +186,7 @@ extern s32
 wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms);
 
 extern s32
-wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 search_enable);
+wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable);
 
 extern s32
 wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
@@ -106,7 +209,7 @@ wl_cfgp2p_bss(struct net_device *ndev, s32 bsscfg_idx, s32 up);
 
 
 extern s32
-wl_cfgp2p_is_p2p_supported(struct wl_priv *wl, struct net_device *ndev);
+wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev);
 
 extern s32
 wl_cfgp2p_down(struct wl_priv *wl);
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c
index 7e387a2..5022d0f 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/wl_iw.c
@@ -104,8 +104,8 @@ bool g_set_essid_before_scan = TRUE;
 #if defined(SOFTAP)
 #define WL_SOFTAP(x)
 static struct net_device *priv_dev;
-static bool		ap_cfg_running = FALSE;
-bool            ap_fw_loaded = FALSE;
+bool		ap_cfg_running = FALSE;
+bool		ap_fw_loaded = FALSE;
 struct net_device *ap_net_dev = NULL;
 tsk_ctl_t	ap_eth_ctl;  
 static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap);
@@ -1660,7 +1660,7 @@ wl_control_wl_start(struct net_device *dev)
 
 		g_onoff = G_WLAN_SET_ON;
 	}
-	WL_TRACE(("Exited %s \n", __FUNCTION__));
+	WL_TRACE(("Exited %s\n", __FUNCTION__));
 
 	DHD_OS_MUTEX_UNLOCK(&wl_start_lock);
 	return ret;
@@ -8499,8 +8499,10 @@ wl_iw_attach(struct net_device *dev, void * dhdp)
 
 	
 	iscan->iscan_ex_params_p = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL);
-	if (!iscan->iscan_ex_params_p)
+	if (!iscan->iscan_ex_params_p) {
+		kfree(iscan);
 		return -ENOMEM;
+	}
 	iscan->iscan_ex_param_size = params_size;
 
 	
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.h b/drivers/net/wireless/bcmdhd/wl_iw.h
index 35a5033..8b58adc 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.h
+++ b/drivers/net/wireless/bcmdhd/wl_iw.h
@@ -43,9 +43,8 @@
 #define GET_HOME_DWELL  		"HOME="
 #define GET_SCAN_TYPE			"TYPE="
 
-
-#define BAND_GET_CMD				"BANDGET"
-#define BAND_SET_CMD				"BANDSET"
+#define BAND_GET_CMD				"GETBAND"
+#define BAND_SET_CMD				"SETBAND"
 #define DTIM_SKIP_GET_CMD			"DTIMSKIPGET"
 #define DTIM_SKIP_SET_CMD			"DTIMSKIPSET"
 #define SETSUSPEND_CMD				"SETSUSPENDOPT"
-- 
1.7.1


