From 28e20380caf54ad19f50d03839c19d155dedba57 Mon Sep 17 00:00:00 2001
From: Howard M. Harte <hharte@broadcom.com>
Date: Mon, 15 Aug 2011 09:06:07 -0700
Subject: [PATCH 656/696] net: wireless: bcmdhd: Update to 5.90.125.64:
    * Fix for dhd_bus_devreset in dhd_sdio return error 35 when first called.
    * Add combo scan support.
    * Fix PMK caching issue.

Change-Id: Iac9e8591d27ef7240418c79caf0a4ac919ef23f3
Signed-off-by: Howard M. Harte <hharte@broadcom.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
---
 drivers/net/wireless/bcmdhd/dhd_cdc.c          |   10 +-
 drivers/net/wireless/bcmdhd/dhd_common.c       |    8 +-
 drivers/net/wireless/bcmdhd/dhd_linux.c        |    7 +-
 drivers/net/wireless/bcmdhd/dhd_sdio.c         |   12 +-
 drivers/net/wireless/bcmdhd/include/bcmutils.h |    2 +
 drivers/net/wireless/bcmdhd/include/epivers.h  |    8 +-
 drivers/net/wireless/bcmdhd/wl_cfg80211.c      |  497 ++++++++++++++----------
 drivers/net/wireless/bcmdhd/wl_cfg80211.h      |   24 +-
 drivers/net/wireless/bcmdhd/wl_cfgp2p.c        |    7 +-
 9 files changed, 322 insertions(+), 253 deletions(-)

diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c
index 91c461f..fde8a35 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -1920,7 +1920,6 @@ dhd_wlfc_init(dhd_pub_t *dhd)
 		WLFC_FLAGS_CREDIT_STATUS_SIGNALS |
 		WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE : 0;
 
-	dhd->wlfc_state  = NULL;
 
 	/*
 	try to enable/disable signaling by sending "tlv" iovar. if that fails,
@@ -2297,16 +2296,15 @@ dhd_prot_init(dhd_pub_t *dhd)
 		goto done;
 
 
+#ifdef PROP_TXSTATUS
+	ret = dhd_wlfc_init(dhd);
+#endif
+
 	ret = dhd_preinit_ioctls(dhd);
 
 	/* Always assumes wl for now */
 	dhd->iswl = TRUE;
 
-#ifdef PROP_TXSTATUS
-	ret = dhd_wlfc_init(dhd);
-#endif
-	goto done;
-
 done:
 	return ret;
 }
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index 582ed8c..2ad6186 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -1533,6 +1533,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 	uint32 dongle_align = DHD_SDALIGN;
 	uint32 glom = 0;
 	uint bcn_timeout = 4;
+	uint retry_max = 3;
 	int arpoe = 1;
 	int arp_ol = 0xf;
 	int scan_assoc_time = 40;
@@ -1610,8 +1611,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif /* SET_RANDOM_MAC_SOFTAP */
 
 	DHD_ERROR(("Firmware up: Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
-	       dhd->mac.octet[0], dhd->mac.octet[1], dhd->mac.octet[2],
-	       dhd->mac.octet[3], dhd->mac.octet[4], dhd->mac.octet[5]));
+	           dhd->mac.octet[0], dhd->mac.octet[1], dhd->mac.octet[2],
+	           dhd->mac.octet[3], dhd->mac.octet[4], dhd->mac.octet[5]));
 
 	/* Set Country code  */
 	if (dhd->dhd_cspec.ccode[0] != 0) {
@@ -1651,6 +1652,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 	/* 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));
 	dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+	/* Setup assoc_retry_max count to reconnect target AP in dongle */
+	bcm_mkiovar("assoc_retry_max", (char *)&retry_max, 4, iovbuf, sizeof(iovbuf));
+	dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
 #ifdef AP
 	/* Turn off MPC in AP mode */
 	bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf));
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 77decc5..d07b3ca 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -443,11 +443,9 @@ static void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf);
 static void dhd_dump_htsfhisto(histo_t *his, char *s);
 #endif /* WLMEDIA_HTSF */
 
-extern s32 wl_cfg80211_ifdel_ops(struct net_device *net);
-
 /* Monitor interface */
-extern int dhd_monitor_init(void *dhd_pub);
-extern int dhd_monitor_uninit(void);
+int dhd_monitor_init(void *dhd_pub);
+int dhd_monitor_uninit(void);
 
 
 #if defined(CONFIG_WIRELESS_EXT)
@@ -2261,7 +2259,6 @@ dhd_open(struct net_device *net)
 	if (ifidx == 0) {
 		atomic_set(&dhd->pend_8021x_cnt, 0);
 #if defined(WL_CFG80211)
-		printf("\n cfg %s\n", dhd_version);
 		wl_android_wifi_on(net);
 #endif
 
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index 9f7c416..50bc7e4 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -52,6 +52,7 @@
 #include <sbsdio.h>
 #include <sbsdpcmdev.h>
 #include <bcmsdpcm.h>
+#include <bcmsdbus.h>
 
 #include <proto/ethernet.h>
 #include <proto/802.1d.h>
@@ -360,7 +361,7 @@ static const uint retry_limit = 2;
 static bool forcealign;
 
 /* Flag to indicate if we should download firmware on driver load */
-uint dhd_download_fw_on_driverload = TRUE;
+uint dhd_download_fw_on_driverload = FALSE;
 
 #define ALIGNMENT  4
 
@@ -6221,10 +6222,13 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
 
 			dhd_os_sdunlock(dhdp);
 		} else {
-			bcmerror = BCME_NOTDOWN;
-			DHD_ERROR(("%s: Set DEVRESET=FALSE invoked when device is on\n",
+			DHD_INFO(("%s called when dongle is not in reset\n",
 				__FUNCTION__));
-			bcmerror = BCME_SDIO_ERROR;
+			DHD_INFO(("Will call dhd_bus_start instead\n"));
+			sdioh_start(NULL, 1);
+			if ((bcmerror = dhd_bus_start(dhdp)) != 0)
+				DHD_ERROR(("%s: dhd_bus_start fail with %d\n",
+					__FUNCTION__, bcmerror));
 		}
 	}
 	return bcmerror;
diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h
index f7f2300..530036f 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmutils.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmutils.h
@@ -140,7 +140,9 @@ typedef bool (*ifpkt_cb_t)(void*, int);
 #define SHARED_POOL		((struct pktpool *)NULL)
 #endif 
 
+#ifndef PKTPOOL_LEN_MAX
 #define PKTPOOL_LEN_MAX		40
+#endif
 #define PKTPOOL_CB_MAX		3
 
 struct pktpool;
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index b94174e..752484b 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	60
+#define	EPI_INCREMENTAL_NUMBER	64
 
 #define	EPI_BUILD_NUMBER	0
 
-#define	EPI_VERSION		5, 90, 125, 60
+#define	EPI_VERSION		5, 90, 125, 64
 
-#define	EPI_VERSION_NUM		0x055a7d3c
+#define	EPI_VERSION_NUM		0x055a7d40
 
 #define EPI_VERSION_DEV		5.90.125
 
 
-#define	EPI_VERSION_STR		"5.90.125.60"
+#define	EPI_VERSION_STR		"5.90.125.64"
 
 #endif 
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index ed2e5dd..7f01776 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -2,13 +2,13 @@
  * Linux cfg80211 driver
  *
  * 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
@@ -74,7 +74,7 @@
 #include <wl_cfgp2p.h>
 
 static struct sdio_func *cfg80211_sdio_func;
-static struct wl_dev *wl_cfg80211_dev;
+static struct wl_priv *wlcfg_drv_priv;
 
 u32 wl_dbg_level = WL_DBG_ERR;
 
@@ -339,8 +339,7 @@ static u32 wl_get_ielen(struct wl_priv *wl);
 
 static s32 wl_mode_to_nl80211_iftype(s32 mode);
 
-static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
-	struct device *dev);
+static struct wireless_dev *wl_alloc_wdev(struct device *sdiofunc_dev);
 static void wl_free_wdev(struct wl_priv *wl);
 
 static s32 wl_inform_bss(struct wl_priv *wl);
@@ -365,12 +364,6 @@ static void wl_deinit_priv_mem(struct wl_priv *wl);
 static void wl_delay(u32 ms);
 
 /*
- * store/restore cfg80211 instance data
- */
-static void wl_set_drvdata(struct wl_dev *dev, void *data);
-static void *wl_get_drvdata(struct wl_dev *dev);
-
-/*
  * ibss mode utilities
  */
 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
@@ -423,9 +416,9 @@ static void wl_iscan_timer(unsigned long data);
 static void wl_term_iscan(struct wl_priv *wl);
 static s32 wl_init_scan(struct wl_priv *wl);
 static s32 wl_iscan_thread(void *data);
-static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
+static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
 	u16 action);
-static s32 wl_do_iscan(struct wl_priv *wl);
+static s32 wl_do_iscan(struct wl_priv *wl,  struct cfg80211_scan_request *request);
 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
 static s32 wl_invoke_iscan(struct wl_priv *wl);
 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
@@ -474,23 +467,11 @@ int dhd_monitor_init(void *dhd_pub);
 int dhd_monitor_uninit(void);
 int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
 
-#define WL_PRIV_GET() 							\
-	({								\
-	struct wl_iface *ci = NULL;					\
-	if (unlikely(!(wl_cfg80211_dev && 				\
-		(ci = wl_get_drvdata(wl_cfg80211_dev))))) {		\
-		WL_ERR(("wl_cfg80211_dev is unavailable\n"));		\
-		BUG();							\
-	} 								\
-	ci_to_wl(ci);							\
-})
-
-#define CHECK_SYS_UP()							\
+#define CHECK_SYS_UP(wlpriv)							\
 do {									\
-	struct wl_priv *wl = WL_PRIV_GET();			\
-	if (unlikely(!wl_get_drv_status(wl, READY))) {	\
+	if (unlikely(!wl_get_drv_status(wlpriv, READY))) {	\
 		WL_INFO(("device is not ready : status (%d)\n",		\
-			(int)wl->status));				\
+			(int)wlpriv->status));			\
 		return -EIO;						\
 	}								\
 } while (0)
@@ -876,11 +857,10 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
 	s32 index = 0;
 	s32 mode = 0;
 	chanspec_t chspec;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct net_device *_ndev;
 	dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
 	int (*net_attach)(dhd_pub_t *dhdp, int ifidx);
-
 	WL_DBG(("if name: %s, type: %d\n", name, type));
 	switch (type) {
 	case NL80211_IFTYPE_ADHOC:
@@ -981,7 +961,6 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
 			wl_set_drv_status(wl, READY);
 			wl->p2p->vif_created = true;
 			set_mode_by_netdev(wl, _ndev, mode);
-			wl = wdev_to_wl(vwdev);
 			net_attach =  wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
 			rtnl_unlock();
 			if (net_attach && !net_attach(dhd, _ndev->ifindex))
@@ -1010,10 +989,9 @@ static s32
 wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
 {
 	struct ether_addr p2p_mac;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	s32 timeout = -1;
 	s32 ret = 0;
-
 	if (wl->p2p_supported) {
 		memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
 		if (wl->p2p->vif_created) {
@@ -1052,7 +1030,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
 	s32 wlif_type;
 	s32 mode = 0;
 	chanspec_t chspec;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	WL_DBG(("Enter \n"));
 	switch (type) {
 	case NL80211_IFTYPE_MONITOR:
@@ -1121,7 +1099,7 @@ s32
 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx,
 int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	s32 ret = BCME_OK;
 	if (!net) {
 		WL_ERR(("net is NULL\n"));
@@ -1146,7 +1124,7 @@ int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
 s32
 wl_cfg80211_ifdel_ops(struct net_device *net)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 
 	if (!net || !net->name) {
 		WL_DBG(("net is NULL\n"));
@@ -1172,7 +1150,7 @@ wl_cfg80211_ifdel_ops(struct net_device *net)
 s32
 wl_cfg80211_notify_ifdel(struct net_device *net)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 
 
 	if (wl->p2p->vif_created) {
@@ -1208,7 +1186,7 @@ s32
 wl_cfg80211_is_progress_ifadd(void)
 {
 	s32 is_progress = 0;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	if (wl_get_p2p_status(wl, IF_ADD))
 		is_progress = 1;
 	return is_progress;
@@ -1218,7 +1196,7 @@ s32
 wl_cfg80211_is_progress_ifchange(void)
 {
 	s32 is_progress = 0;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	if (wl_get_p2p_status(wl, IF_CHANGING))
 		is_progress = 1;
 	return is_progress;
@@ -1228,7 +1206,7 @@ wl_cfg80211_is_progress_ifchange(void)
 s32
 wl_cfg80211_notify_ifchange(void)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	if (wl_get_p2p_status(wl, IF_CHANGING)) {
 		wl_set_p2p_status(wl, IF_CHANGED);
 		wake_up_interruptible(&wl->dongle_event_wait);
@@ -1236,8 +1214,16 @@ wl_cfg80211_notify_ifchange(void)
 	return 0;
 }
 
-static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
+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;
+	u16 channel;
+	chanspec_t chanspec;
+	s32 i, offset;
+	char *ptr;
+	wlc_ssid_t ssid;
+
 	memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
 	params->bss_type = DOT11_BSSTYPE_ANY;
 	params->scan_type = 0;
@@ -1246,63 +1232,141 @@ static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
 	params->passive_time = -1;
 	params->home_time = -1;
 	params->channel_num = 0;
+	memset(&params->ssid, 0, sizeof(wlc_ssid_t));
+
+	WL_SCAN(("Preparing Scan request\n"));
+	WL_SCAN(("nprobes=%d\n", params->nprobes));
+	WL_SCAN(("active_time=%d\n", params->active_time));
+	WL_SCAN(("passive_time=%d\n", params->passive_time));
+	WL_SCAN(("home_time=%d\n", params->home_time));
+	WL_SCAN(("scan_type=%d\n", params->scan_type));
 
 	params->nprobes = htod32(params->nprobes);
 	params->active_time = htod32(params->active_time);
 	params->passive_time = htod32(params->passive_time);
 	params->home_time = htod32(params->home_time);
-	if (ssid && ssid->SSID_len)
-		memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
 
+	/* Copy channel array if applicable */
+	WL_SCAN(("### List of channelspecs to scan ###\n"));
+	if (n_channels > 0) {
+		for (i = 0; i < n_channels; i++) {
+			chanspec = 0;
+			channel = ieee80211_frequency_to_channel(request->channels[i]->center_freq);
+			if (request->channels[i]->band == IEEE80211_BAND_2GHZ)
+				chanspec |= WL_CHANSPEC_BAND_2G;
+			else
+				chanspec |= WL_CHANSPEC_BAND_5G;
+
+			if (request->channels[i]->flags & IEEE80211_CHAN_NO_HT40) {
+				chanspec |= WL_CHANSPEC_BW_20;
+				chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+			} else {
+				chanspec |= WL_CHANSPEC_BW_40;
+				if (request->channels[i]->flags & IEEE80211_CHAN_NO_HT40PLUS)
+					chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
+				else
+					chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
+			}
+
+			params->channel_list[i] = channel;
+			params->channel_list[i] &= WL_CHANSPEC_CHAN_MASK;
+			params->channel_list[i] |= chanspec;
+			WL_SCAN(("%d Channel spec: %x \n", i, params->channel_list[i]));
+			params->channel_list[i] = htod16(params->channel_list[i]);
+		}
+	} else {
+		WL_SCAN(("Scanning all channels\n"));
+	}
+
+	/* Copy ssid array if applicable */
+	WL_SCAN(("### List of SSIDs to scan ###\n"));
+	if (n_ssids > 0) {
+		offset = offsetof(wl_scan_params_t, channel_list) + n_channels * sizeof(u16);
+		offset = roundup(offset, sizeof(u32));
+		ptr = (char*)params + offset;
+		for (i = 0; i < n_ssids; i++) {
+			memset(&ssid, 0, sizeof(wlc_ssid_t));
+			ssid.SSID_len = request->ssids[i].ssid_len;
+			memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len);
+			if (!ssid.SSID_len)
+				WL_SCAN(("%d: Broadcast scan\n", i));
+			else
+				WL_SCAN(("%d: scan  for  %s size =%d\n", i,
+				ssid.SSID, ssid.SSID_len));
+			memcpy(ptr, &ssid, sizeof(wlc_ssid_t));
+			ptr += sizeof(wlc_ssid_t);
+		}
+	} else {
+		WL_SCAN(("Broadcast scan\n"));
+	}
+	/* Adding mask to channel numbers */
+	params->channel_num =
+	        htod32((n_ssids << WL_SCAN_PARAMS_NSSID_SHIFT) |
+	               (n_channels & WL_SCAN_PARAMS_COUNT_MASK));
 }
 
 static s32
-wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
+wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, u16 action)
 {
+	u32 n_channels;
+	u32 n_ssids;
 	s32 params_size =
-		(WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
+	    (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
 	struct wl_iscan_params *params;
 	s32 err = 0;
 
-	if (ssid && ssid->SSID_len)
-		params_size += sizeof(struct wlc_ssid);
+	if (request != NULL) {
+		n_channels = request->n_channels;
+		n_ssids = request->n_ssids;
+		/* Allocate space for populating ssids in wl_iscan_params struct */
+		if (n_channels % 2)
+			/* If n_channels is odd, add a padd of u16 */
+			params_size += sizeof(u16) * (n_channels + 1);
+		else
+			params_size += sizeof(u16) * n_channels;
+
+		/* Allocate space for populating ssids in wl_iscan_params struct */
+		params_size += sizeof(struct wlc_ssid) * n_ssids;
+	}
 	params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
-	if (unlikely(!params))
-		return -ENOMEM;
-	memset(params, 0, params_size);
-	BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
+	if (!params) {
+		err = -ENOMEM;
+		goto done;
+	}
 
-	wl_iscan_prep(&params->params, ssid);
+	if (request != NULL)
+		wl_scan_prep(&params->params, request);
 
 	params->version = htod32(ISCAN_REQ_VERSION);
 	params->action = htod16(action);
 	params->scan_duration = htod16(0);
 
-	/* params_size += offsetof(wl_iscan_params_t, params); */
+	if (params_size + sizeof("iscan") >= WLC_IOCTL_MEDLEN) {
+		WL_ERR(("ioctl buffer length is not sufficient\n"));
+		err = -ENOMEM;
+		goto done;
+	}
 	err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
-		iscan->ioctl_buf, WLC_IOCTL_SMLEN);
+		iscan->ioctl_buf, WLC_IOCTL_MEDLEN);
 	if (unlikely(err)) {
 		if (err == -EBUSY) {
-		WL_INFO(("system busy : iscan canceled\n"));
+			WL_INFO(("system busy : iscan canceled\n"));
 		} else {
 			WL_ERR(("error (%d)\n", err));
 		}
 	}
 	kfree(params);
+done:
 	return err;
 }
 
-static s32 wl_do_iscan(struct wl_priv *wl)
+static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request)
 {
 	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
 	struct net_device *ndev = wl_to_prmry_ndev(wl);
-	struct wlc_ssid ssid;
 	s32 passive_scan;
 	s32 err = 0;
 
-	/* Broadcast scan by default */
-	memset(&ssid, 0, sizeof(ssid));
-
 	iscan->state = WL_ISCAN_STATE_SCANING;
 
 	passive_scan = wl->active_scan ? 0 : 1;
@@ -1313,7 +1377,7 @@ static s32 wl_do_iscan(struct wl_priv *wl)
 		return err;
 	}
 	wl->iscan_kickstart = true;
-	wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
+	wl_run_iscan(iscan, request, WL_SCAN_ACTION_START);
 	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
 	iscan->timer_on = 1;
 
@@ -1321,9 +1385,12 @@ static s32 wl_do_iscan(struct wl_priv *wl)
 }
 
 static s32
-wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint16 action)
+wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
+	struct cfg80211_scan_request *request, uint16 action)
 {
 	s32 err = BCME_OK;
+	u32 n_channels;
+	u32 n_ssids;
 	s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
 	wl_escan_params_t *params;
 	struct cfg80211_scan_request *scan_request = wl->scan_request;
@@ -1337,31 +1404,37 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint
 	if (!wl->p2p_supported || ((ndev == wl_to_prmry_ndev(wl)) &&
 		!p2p_scan(wl))) {
 		/* LEGACY SCAN TRIGGER */
-		WL_DBG(("LEGACY SCAN START\n"));
-		if (ssid && ssid->SSID_len) {
-			params_size += sizeof(wlc_ssid_t);
+		WL_SCAN((" LEGACY E-SCAN START\n"));
+
+		if (request != NULL) {
+			n_channels = request->n_channels;
+			n_ssids = request->n_ssids;
+			/* Allocate space for populating ssids in wl_iscan_params struct */
+			if (n_channels % 2)
+				/* If n_channels is odd, add a padd of u16 */
+				params_size += sizeof(u16) * (n_channels + 1);
+			else
+				params_size += sizeof(u16) * n_channels;
+
+			/* Allocate space for populating ssids in wl_iscan_params struct */
+			params_size += sizeof(struct wlc_ssid) * n_ssids;
 		}
-		params = (wl_escan_params_t *) kmalloc(params_size, GFP_KERNEL);
-
-		if (params == NULL)
-			return -ENOMEM;
-
-		memset(params, 0, params_size);
-		memcpy(&params->params.bssid, &ether_bcast, ETHER_ADDR_LEN);
-		params->params.bss_type = DOT11_BSSTYPE_ANY;
-		params->params.scan_type = 0;
-		params->params.nprobes = htod32(-1);
-		params->params.active_time = htod32(-1);
-		params->params.passive_time = htod32(-1);
-		params->params.home_time = htod32(-1);
-		params->params.channel_num = 0;
-		if (ssid && ssid->SSID_len) {
-			memcpy(params->params.ssid.SSID, ssid->SSID, ssid->SSID_len);
-			params->params.ssid.SSID_len = htod32(ssid->SSID_len);
+		params = (wl_escan_params_t *) kzalloc(params_size, GFP_KERNEL);
+		if (params == NULL) {
+			err = -ENOMEM;
+			goto exit;
 		}
+
+		if (request != NULL)
+			wl_scan_prep(&params->params, request);
 		params->version = htod32(ESCAN_REQ_VERSION);
 		params->action =  htod16(action);
 		params->sync_id = htod16(0x1234);
+		if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) {
+			WL_ERR(("ioctl buffer length not sufficient\n"));
+			err = -ENOMEM;
+			goto exit;
+		}
 		wldev_iovar_setbuf(ndev, "escan", params, params_size,
 			wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
 		kfree(params);
@@ -1370,7 +1443,7 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint
 		/* P2P SCAN TRIGGER */
 		if (scan_request && scan_request->n_channels) {
 			num_chans = scan_request->n_channels;
-			WL_INFO((" chann number : %d\n", num_chans));
+			WL_SCAN((" chann number : %d\n", num_chans));
 			default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
 				GFP_KERNEL);
 			if (default_chan_list == NULL) {
@@ -1407,12 +1480,13 @@ exit:
 
 
 static s32
-wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wlc_ssid_t *ssid)
+wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev,
+	struct cfg80211_scan_request *request)
 {
 	s32 err = BCME_OK;
 	s32 passive_scan;
 	wl_scan_results_t *results;
-	WL_DBG(("Enter \n"));
+	WL_SCAN(("Enter \n"));
 
 	wl->escan_info.wiphy = wiphy;
 	wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
@@ -1428,7 +1502,7 @@ 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_run_escan(wl, ndev, ssid, WL_SCAN_ACTION_START);
+	wl_run_escan(wl, ndev, request, WL_SCAN_ACTION_START);
 	return err;
 }
 
@@ -1437,15 +1511,16 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 	struct cfg80211_scan_request *request,
 	struct cfg80211_ssid *this_ssid)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct cfg80211_ssid *ssids;
 	struct wl_scan_req *sr = wl_to_sr(wl);
-	wlc_ssid_t ssid_info;
 	s32 passive_scan;
 	bool iscan_req;
 	bool escan_req;
 	bool spec_scan;
+	bool p2p_ssid;
 	s32 err = 0;
+	s32 i;
 
 	if (unlikely(wl_get_drv_status(wl, SCANNING))) {
 		WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
@@ -1456,6 +1531,10 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 			(int)wl->status));
 		return -EAGAIN;
 	}
+	if (request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
+		WL_ERR(("n_ssids > WL_SCAN_PARAMS_SSID_MAX\n"));
+		return -EOPNOTSUPP;
+	}
 
 	WL_DBG(("wiphy (%p)\n", wiphy));
 
@@ -1463,11 +1542,18 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 	spec_scan = false;
 	if (request) {		/* scan bss */
 		ssids = request->ssids;
-		if (wl->iscan_on && (!ssids || !ssids->ssid_len)) {
+		if (wl->iscan_on && (!ssids || !ssids->ssid_len || request->n_ssids != 1)) {
 			iscan_req = true;
 		} else if (wl->escan_on) {
 			escan_req = true;
-			if (ssids->ssid_len && IS_P2P_SSID(ssids->ssid)) {
+			p2p_ssid = false;
+			for (i = 0; i < request->n_ssids; i++) {
+				if (ssids[i].ssid_len && IS_P2P_SSID(ssids[i].ssid)) {
+					p2p_ssid = true;
+					break;
+				}
+			}
+			if (p2p_ssid) {
 				if (wl->p2p_supported) {
 					/* p2p scan trigger */
 					if (p2p_on(wl) == false) {
@@ -1477,7 +1563,6 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 					}
 					p2p_scan(wl) = true;
 				}
-
 			} else {
 				/* legacy scan trigger
 				 * So, we have to disable p2p discovery if p2p discovery is on
@@ -1510,17 +1595,12 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 	wl->scan_request = request;
 	wl_set_drv_status(wl, SCANNING);
 	if (iscan_req) {
-		err = wl_do_iscan(wl);
+		err = wl_do_iscan(wl, request);
 		if (likely(!err))
 			return err;
 		else
 			goto scan_out;
 	} else if (escan_req) {
-		WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
-			ssids->ssid, ssids->ssid_len));
-
-		memcpy(ssid_info.SSID, ssids->ssid, ssids->ssid_len);
-		ssid_info.SSID_len = ssids->ssid_len;
 		if (wl->p2p_supported) {
 			if (p2p_on(wl) && p2p_scan(wl)) {
 
@@ -1532,7 +1612,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 				}
 			}
 		}
-		err = wl_do_escan(wl, wiphy, ndev, &ssid_info);
+		err = wl_do_escan(wl, wiphy, ndev, request);
 		if (likely(!err))
 			return err;
 		else
@@ -1546,18 +1626,18 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 		if (sr->ssid.SSID_len) {
 			memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
 			sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
-			WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
+			WL_SCAN(("Specific scan ssid=\"%s\" len=%d\n",
 				sr->ssid.SSID, sr->ssid.SSID_len));
 			spec_scan = true;
 		} else {
-			WL_DBG(("Broadcast scan\n"));
+			WL_SCAN(("Broadcast scan\n"));
 		}
-		WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
+		WL_SCAN(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
 		passive_scan = wl->active_scan ? 0 : 1;
 		err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
 			&passive_scan, sizeof(passive_scan), false);
 		if (unlikely(err)) {
-			WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
+			WL_SCAN(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
 			goto scan_out;
 		}
 		err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
@@ -1586,9 +1666,10 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 	struct cfg80211_scan_request *request)
 {
 	s32 err = 0;
+	struct wl_priv *wl = wiphy_priv(wiphy);
 
 	WL_DBG(("Enter \n"));
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
 	if (unlikely(err)) {
 		WL_ERR(("scan error (%d)\n", err));
@@ -1679,11 +1760,11 @@ static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
 
 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
 {
-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+	struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy);
 	struct net_device *ndev = wl_to_prmry_ndev(wl);
 	s32 err = 0;
 
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
 		(wl->conf->rts_threshold != wiphy->rts_threshold)) {
 		wl->conf->rts_threshold = wiphy->rts_threshold;
@@ -1721,7 +1802,7 @@ static s32
 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 	struct cfg80211_ibss_params *params)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct cfg80211_bss *bss;
 	struct ieee80211_channel *chan;
 	struct wl_join_params join_params;
@@ -1730,7 +1811,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 	s32 err = 0;
 
 	WL_TRACE(("In\n"));
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	if (params->bssid) {
 		WL_ERR(("Invalid bssid\n"));
 		return -EOPNOTSUPP;
@@ -1791,10 +1872,10 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 
 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	s32 err = 0;
 
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	wl_link_down(wl);
 
 	return err;
@@ -1803,7 +1884,7 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 static s32
 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	struct wl_security *sec;
 	s32 val = 0;
 	s32 err = 0;
@@ -1833,7 +1914,7 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
 static s32
 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	struct wl_security *sec;
 	s32 val = 0;
 	s32 err = 0;
@@ -1872,7 +1953,7 @@ wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
 static s32
 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	struct wl_security *sec;
 	s32 pval = 0;
 	s32 gval = 0;
@@ -1944,7 +2025,7 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
 static s32
 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	struct wl_security *sec;
 	s32 val = 0;
 	s32 err = 0;
@@ -2002,7 +2083,7 @@ static s32
 wl_set_set_sharedkey(struct net_device *dev,
 	struct cfg80211_connect_params *sme)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	struct wl_security *sec;
 	struct wl_wsec_key key;
 	s32 val;
@@ -2068,14 +2149,17 @@ static s32
 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	struct cfg80211_connect_params *sme)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct ieee80211_channel *chan = sme->channel;
 	struct wl_join_params join_params;
 	size_t join_params_size;
 	s32 err = 0;
-
+	wpa_ie_fixed_t *wpa_ie;
+	bcm_tlv_t *wpa2_ie;
+	u8* wpaie  = 0;
+	u32 wpaie_len = 0;
 	WL_DBG(("In\n"));
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 
 	/*
 	 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
@@ -2107,8 +2191,25 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 				VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
 		}
 
-	} else {
-		WL_INFO(("No P2PIE in beacon \n"));
+	} else if (dev == wl_to_prmry_ndev(wl)) {
+			/* find the RSN_IE */
+			if ((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len,
+				DOT11_MNG_RSN_ID)) != NULL) {
+				WL_DBG((" WPA2 IE is found\n"));
+			}
+			/* find the WPA_IE */
+			if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)sme->ie,
+				sme->ie_len)) != NULL) {
+				WL_DBG((" WPA IE is found\n"));
+			}
+			if (wpa_ie != NULL || wpa2_ie != NULL) {
+				wpaie = (wpa_ie != NULL) ? (u8 *)wpa_ie : (u8 *)wpa2_ie;
+				wpaie_len = (wpa_ie != NULL) ? wpa_ie->length : wpa2_ie->len;
+				wpaie_len += WPA_RSN_IE_TAG_FIXED_LEN;
+				wldev_iovar_setbuf(dev, "wpaie", wpaie, wpaie_len,
+				ioctlbuf, sizeof(ioctlbuf));
+			}
+
 	}
 
 	if (unlikely(!sme->ssid)) {
@@ -2119,7 +2220,8 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 		wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
 		WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
 			chan->center_freq));
-	}
+	} else
+		wl->channel = 0;
 	WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
 	err = wl_set_wpa_version(dev, sme);
 	if (unlikely(err))
@@ -2179,13 +2281,13 @@ static s32
 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
 	u16 reason_code)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	scb_val_t scbval;
 	bool act = false;
 	s32 err = 0;
 
 	WL_ERR(("Reason %d\n\n\n", reason_code));
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
 	if (likely(act)) {
 		scbval.val = reason_code;
@@ -2207,13 +2309,13 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy,
 	enum nl80211_tx_power_setting type, s32 dbm)
 {
 
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct net_device *ndev = wl_to_prmry_ndev(wl);
 	u16 txpwrmw;
 	s32 err = 0;
 	s32 disable = 0;
 
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	switch (type) {
 	case NL80211_TX_POWER_AUTOMATIC:
 		break;
@@ -2256,13 +2358,13 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy,
 
 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct net_device *ndev = wl_to_prmry_ndev(wl);
 	s32 txpwrdbm;
 	u8 result;
 	s32 err = 0;
 
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
 	if (unlikely(err)) {
 		WL_ERR(("error (%d)\n", err));
@@ -2278,14 +2380,14 @@ static s32
 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
 	u8 key_idx, bool unicast, bool multicast)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	u32 index;
 	s32 wsec;
 	s32 err = 0;
 	s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
 
 	WL_DBG(("key index (%d)\n", key_idx));
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
 	if (unlikely(err)) {
 		WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
@@ -2308,7 +2410,7 @@ static s32
 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
 	u8 key_idx, const u8 *mac_addr, struct key_params *params)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct wl_wsec_key key;
 	s32 err = 0;
 	s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
@@ -2407,10 +2509,10 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 	s32 err = 0;
 	u8 keybuf[8];
 	s32 bssidx = 0;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	s32 mode = get_mode_by_netdev(wl, dev);
 	WL_DBG(("key index (%d)\n", key_idx));
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 
 	bssidx = wl_cfgp2p_find_idx(wl, dev);
 
@@ -2508,12 +2610,12 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
 	u8 key_idx, bool pairwise, const u8 *mac_addr)
 {
 	struct wl_wsec_key key;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	s32 err = 0;
 	s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
 
 	WL_DBG(("Enter\n"));
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	memset(&key, 0, sizeof(key));
 
 	key.index = (u32) key_idx;
@@ -2557,14 +2659,14 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
 {
 	struct key_params params;
 	struct wl_wsec_key key;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct wl_security *sec;
 	s32 wsec;
 	s32 err = 0;
 	s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
 
 	WL_DBG(("key index (%d)\n", key_idx));
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	memset(&key, 0, sizeof(key));
 	key.index = key_idx;
 	swap_key_to_BE(&key);
@@ -2610,7 +2712,6 @@ wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
 	struct net_device *dev, u8 key_idx)
 {
 	WL_INFO(("Not supported\n"));
-	CHECK_SYS_UP();
 	return -EOPNOTSUPP;
 }
 
@@ -2618,13 +2719,13 @@ static s32
 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
 	u8 *mac, struct station_info *sinfo)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	scb_val_t scb_val;
 	int rssi;
 	s32 rate;
 	s32 err = 0;
 
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	if (unlikely
 		(memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
 		WL_ERR(("Wrong Mac address\n"));
@@ -2675,8 +2776,9 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
 {
 	s32 pm;
 	s32 err = 0;
+	struct wl_priv *wl = wiphy_priv(wiphy);
 
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	pm = enabled ? PM_FAST : PM_OFF;
 	pm = htod32(pm);
 	WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
@@ -2720,7 +2822,7 @@ static __used u32 wl_find_msb(u16 bit16)
 
 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	s32 err = 0;
 
 	if (unlikely(!wl_get_drv_status(wl, READY))) {
@@ -2740,9 +2842,8 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
 #endif
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	s32 err = 0;
-
 	if (unlikely(!wl_get_drv_status(wl, READY))) {
 		WL_INFO(("device is not ready : status (%d)\n",
 			(int)wl->status));
@@ -2766,7 +2867,7 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
 	s32 err)
 {
 	int i, j;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	struct net_device *primary_dev = wl_to_prmry_ndev(wl);
 
 	/* Firmware is supporting pmk list only for STA interface i.e. primary interface
@@ -2774,7 +2875,7 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
 	  * Do we really need to support PMK cache in P2P in firmware?
 	*/
 	if (primary_dev != dev) {
-		WL_ERR(("Not supporting Flushing pmklist on virtual"
+		WL_INFO(("Not supporting Flushing pmklist on virtual"
 			" interfaces than primary interface\n"));
 		return err;
 	}
@@ -2799,11 +2900,11 @@ static s32
 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
 	struct cfg80211_pmksa *pmksa)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	s32 err = 0;
 	int i;
 
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
 		if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
 			ETHER_ADDR_LEN))
@@ -2819,10 +2920,10 @@ wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
 		err = -EINVAL;
 	}
 	WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
-		&wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
+		&wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].BSSID));
 	for (i = 0; i < WPA2_PMKID_LEN; i++) {
 		WL_DBG(("%02x\n",
-			wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
+			wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].
 			PMKID[i]));
 	}
 
@@ -2835,12 +2936,12 @@ static s32
 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
 	struct cfg80211_pmksa *pmksa)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct _pmkid_list pmkid;
 	s32 err = 0;
 	int i;
 
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
 	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
 
@@ -2881,9 +2982,9 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
 static s32
 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	s32 err = 0;
-	CHECK_SYS_UP();
+	CHECK_SYS_UP(wl);
 	memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
 	err = wl_update_pmklist(dev, wl->pmk_list, err);
 	return err;
@@ -2959,7 +3060,7 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
 	s32 target_channel;
 
 	s32 err = BCME_OK;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
 	WL_DBG(("Enter, netdev_ifidx: %d \n", dev->ifindex));
 	if (likely(wl_get_drv_status(wl, SCANNING))) {
@@ -3015,7 +3116,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 	wifi_p2p_ie_t *p2p_ie;
 	wpa_ie_fixed_t *wps_ie;
 	const struct ieee80211_mgmt *mgmt;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
 	s32 err = BCME_OK;
 	s32 bssidx = 0;
@@ -3470,7 +3571,7 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
 	s32 err = BCME_OK;
 	bcm_tlv_t *ssid_ie;
 	wlc_ssid_t ssid;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wiphy_priv(wiphy);
 	struct wl_join_params join_params;
 	wpa_ie_fixed_t *wps_ie;
 	wpa_ie_fixed_t *wpa_ie;
@@ -3760,7 +3861,6 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
 static s32
 wl_cfg80211_drv_start(struct wiphy *wiphy, struct net_device *dev)
 {
-	/* struct wl_priv *wl = wiphy_to_wl(wiphy); */
 	s32 err = 0;
 
 	printk("Android driver start command\n");
@@ -3770,7 +3870,6 @@ wl_cfg80211_drv_start(struct wiphy *wiphy, struct net_device *dev)
 static s32
 wl_cfg80211_drv_stop(struct wiphy *wiphy, struct net_device *dev)
 {
-	/* struct wl_priv *wl = wiphy_to_wl(wiphy); */
 	s32 err = 0;
 
 	printk("Android driver stop command\n");
@@ -3833,28 +3932,26 @@ static s32 wl_mode_to_nl80211_iftype(s32 mode)
 	return err;
 }
 
-static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
-	struct device *dev)
+static struct wireless_dev *wl_alloc_wdev(struct device *sdiofunc_dev)
 {
 	struct wireless_dev *wdev;
 	s32 err = 0;
-	struct wl_priv *wl;
 	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) + sizeof_iface);
+	    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;
 	}
-	set_wiphy_dev(wdev->wiphy, dev);
-	wl = wiphy_to_wl(wdev->wiphy);
+	set_wiphy_dev(wdev->wiphy, sdiofunc_dev);
 	wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
-	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
+	/* Report  how many SSIDs Driver can support per Scan request */
+	wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX;
 	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
 	wdev->wiphy->interface_modes =
 	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC)
@@ -3902,7 +3999,7 @@ wiphy_new_out:
 static void wl_free_wdev(struct wl_priv *wl)
 {
 	int i;
-	struct wireless_dev *wdev = wl_to_wdev(wl);
+	struct wireless_dev *wdev = wl->wdev;
 
 	if (unlikely(!wdev)) {
 		WL_ERR(("wdev is invalid\n"));
@@ -4178,12 +4275,10 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
 		} else if (wl_is_linkdown(wl, e)) {
 			if (wl_get_drv_status(wl, CONNECTED)) {
 				printk("link down, call cfg80211_disconnected ");
-				rtnl_lock();
 				cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
 				wl_clr_drv_status(wl, CONNECTED);
 				wl_link_down(wl);
 				wl_init_prof(wl->profile);
-				rtnl_unlock();
 			} else if (wl_get_drv_status(wl, CONNECTING)) {
 				printk("link down, during connecting");
 				wl_bss_connect_done(wl, ndev, e, data, false);
@@ -4211,24 +4306,22 @@ wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
 	s32 err = 0;
 	u32 event = be32_to_cpu(e->event_type);
 	u32 status = be32_to_cpu(e->status);
-
 	WL_DBG(("Enter \n"));
 	if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
-		if (test_bit(WL_STATUS_CONNECTED, &wl->status))
+		if (wl_get_drv_status(wl, CONNECTED))
 			wl_bss_roaming_done(wl, ndev, e, data);
 		else
 			wl_bss_connect_done(wl, ndev, e, data, true);
 		act = true;
 		wl_update_prof(wl, e, &act, WL_PROF_ACT);
 	}
-
 	return err;
 }
 
 static __used s32
 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	u32 buflen;
 
 	buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
@@ -4241,7 +4334,7 @@ static s32
 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
 	s32 buf_len)
 {
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 	u32 len;
 	s32 err = 0;
 
@@ -4449,6 +4542,7 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
 	wl_get_assoc_ies(wl, ndev);
 	memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
 	wl_update_bss_info(wl, ndev);
+	wl_update_pmklist(ndev, wl->pmk_list, err);
 	cfg80211_roamed(ndev,
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
 		NULL,
@@ -4478,6 +4572,7 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
 			wl_get_assoc_ies(wl, ndev);
 			memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
 			wl_update_bss_info(wl, ndev);
+			wl_update_pmklist(ndev, wl->pmk_list, err);
 		}
 		cfg80211_connect_result(ndev,
 			(u8 *)&wl->bssid,
@@ -5262,7 +5357,7 @@ s32 wl_cfg80211_sysctl_export_devaddr(void *data)
 	 * so that wpa_supplicant can access it
 	 */
 	dhd_pub_t *dhd = (dhd_pub_t *)data;
-	struct wl_priv *wl = WL_PRIV_GET();
+	struct wl_priv *wl = wlcfg_drv_priv;
 
 	wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
 
@@ -5282,7 +5377,7 @@ s32 wl_cfg80211_attach_post(struct net_device *ndev)
 		WL_ERR(("ndev is invaild\n"));
 		return -ENODEV;
 	}
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 	if (wl && !wl_get_drv_status(wl, READY)) {
 			if (wl->wdev &&
 				wl_cfgp2p_supported(wl, ndev)) {
@@ -5307,7 +5402,6 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
 {
 	struct wireless_dev *wdev;
 	struct wl_priv *wl;
-	struct wl_iface *ci;
 	s32 err = 0;
 
 	WL_TRACE(("In\n"));
@@ -5315,23 +5409,16 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
 		WL_ERR(("ndev is invaild\n"));
 		return -ENODEV;
 	}
-	wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
-	if (unlikely(!wl_cfg80211_dev)) {
-		WL_ERR(("wl_cfg80211_dev is invalid\n"));
-		return -ENOMEM;
-	}
 	WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
-	wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
+	wdev = wl_alloc_wdev(&wl_cfg80211_get_sdio_func()->dev);
 	if (unlikely(IS_ERR(wdev)))
 		return -ENOMEM;
 
 	wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
-	wl = wdev_to_wl(wdev);
+	wl = (struct wl_priv *)wiphy_priv(wdev->wiphy);
 	wl->wdev = wdev;
 	wl->pub = data;
 
-	ci = (struct wl_iface *)wl_to_ci(wl);
-	ci->wl = wl;
 	ndev->ieee80211_ptr = wdev;
 	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
 	wdev->netdev = ndev;
@@ -5354,7 +5441,7 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
 		goto cfg80211_attach_out;
 	}
 #endif
-	wl_set_drvdata(wl_cfg80211_dev, ci);
+	wlcfg_drv_priv = wl;
 	return err;
 
 cfg80211_attach_out:
@@ -5367,7 +5454,7 @@ void wl_cfg80211_detach(void)
 {
 	struct wl_priv *wl;
 
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 
 	WL_TRACE(("In\n"));
 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
@@ -5378,9 +5465,7 @@ void wl_cfg80211_detach(void)
 	if (wl->p2p_supported)
 		wl_cfgp2p_deinit_priv(wl);
 	wl_deinit_priv(wl);
-	wl_set_drvdata(wl_cfg80211_dev, NULL);
-	kfree(wl_cfg80211_dev);
-	wl_cfg80211_dev = NULL;
+	wlcfg_drv_priv = NULL;
 	wl_clear_sdio_func();
 	wl_free_wdev(wl);
 }
@@ -5421,7 +5506,6 @@ static s32 wl_event_handler(void *data)
 		}
 		wl_put_event(e);
 	}
-
 	WL_DBG(("%s was terminated\n", __func__));
 	complete_and_exit(&tsk->completed, 0);
 	return 0;
@@ -5431,7 +5515,7 @@ void
 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();
+	struct wl_priv *wl = wlcfg_drv_priv;
 
 #if (WL_DBG_LEVEL > 0)
 	s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
@@ -5635,14 +5719,12 @@ static s32 wl_dongle_eventmsg(struct net_device *ndev)
 	setbit(eventmask, WLC_E_DISASSOC_IND);
 	setbit(eventmask, WLC_E_DISASSOC);
 	setbit(eventmask, WLC_E_JOIN);
+	setbit(eventmask, WLC_E_ROAM);
 	setbit(eventmask, WLC_E_ASSOC_IND);
-	setbit(eventmask, WLC_E_PSK_SUP);
 	setbit(eventmask, WLC_E_LINK);
-	setbit(eventmask, WLC_E_NDIS_LINK);
 	setbit(eventmask, WLC_E_MIC_ERROR);
 	setbit(eventmask, WLC_E_PMKID_CACHE);
 	setbit(eventmask, WLC_E_TXFAIL);
-	setbit(eventmask, WLC_E_JOIN_START);
 	setbit(eventmask, WLC_E_SCAN_COMPLETE);
 	setbit(eventmask, WLC_E_ACTION_FRAME_RX);
 	setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE);
@@ -6072,6 +6154,7 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
 	wl_clr_drv_status(wl, READY);
 	wl_clr_drv_status(wl, SCANNING);
 	wl_clr_drv_status(wl, SCAN_ABORTING);
+	wl_clr_drv_status(wl, CONNECTING);
 	wl_clr_drv_status(wl, CONNECTED);
 	if (wl_get_drv_status(wl, AP_CREATED)) {
 		wl_clr_drv_status(wl, AP_CREATED);
@@ -6097,7 +6180,7 @@ s32 wl_cfg80211_up(void)
 	s32 err = 0;
 
 	WL_TRACE(("In\n"));
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 	mutex_lock(&wl->usr_sync);
 	wl_cfg80211_attach_post(wl_to_prmry_ndev(wl));
 	err = __wl_cfg80211_up(wl);
@@ -6114,7 +6197,7 @@ s32 wl_cfg80211_down(void)
 	s32 err = 0;
 
 	WL_TRACE(("In\n"));
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 	mutex_lock(&wl->usr_sync);
 	err = __wl_cfg80211_down(wl);
 	mutex_unlock(&wl->usr_sync);
@@ -6311,22 +6394,12 @@ static void wl_delay(u32 ms)
 	}
 }
 
-static void wl_set_drvdata(struct wl_dev *dev, void *data)
-{
-	dev->driver_data = data;
-}
-
-static void *wl_get_drvdata(struct wl_dev *dev)
-{
-	return dev->driver_data;
-}
-
 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
 {
 	const struct firmware *fw_entry;
 	struct wl_priv *wl;
 
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 
 	fw_entry = wl->fw->fw_entry;
 
@@ -6342,7 +6415,7 @@ void wl_cfg80211_release_fw(void)
 {
 	struct wl_priv *wl;
 
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 	release_firmware(wl->fw->fw_entry);
 	wl->fw->ptr = 0;
 }
@@ -6355,7 +6428,7 @@ void *wl_cfg80211_request_fw(s8 *file_name)
 
 	WL_TRACE(("In\n"));
 	WL_DBG(("file name : \"%s\"\n", file_name));
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 
 	if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
 		err = request_firmware(&wl->fw->fw_entry, file_name,
@@ -6400,7 +6473,7 @@ s8 *wl_cfg80211_get_fwname(void)
 {
 	struct wl_priv *wl;
 
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 	strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
 	return wl->fw->fw_name;
 }
@@ -6409,7 +6482,7 @@ s8 *wl_cfg80211_get_nvramname(void)
 {
 	struct wl_priv *wl;
 
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 	strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
 	return wl->fw->nvram_name;
 }
@@ -6420,7 +6493,7 @@ s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pd
 	dhd_pub_t *dhd_pub;
 	struct ether_addr p2pif_addr;
 
-	wl = WL_PRIV_GET();
+	wl = wlcfg_drv_priv;
 	dhd_pub = (dhd_pub_t *)wl->pub;
 	wl_cfgp2p_generate_bss_mac(&dhd_pub->mac, p2pdev_addr, &p2pif_addr);
 
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 9611076..8116d63 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -52,6 +52,7 @@ struct wl_ibss;
 #define dtohchanspec(i) i
 
 #define WL_DBG_NONE	0
+#define WL_DBG_SCAN 	(1 << 3)
 #define WL_DBG_DBG 	(1 << 2)
 #define WL_DBG_INFO	(1 << 1)
 #define WL_DBG_ERR	(1 << 0)
@@ -74,6 +75,13 @@ do {										\
 			printk args;						\
 		}								\
 } while (0)
+#define	WL_SCAN(args)								\
+do {									\
+	if (wl_dbg_level & WL_DBG_SCAN) {			\
+		printk(KERN_ERR "CFG80211-SCAN) %s :", __func__);	\
+		printk args;							\
+	}									\
+} while (0)
 #if (WL_DBG_LEVEL > 0)
 #define	WL_DBG(args)								\
 do {									\
@@ -87,7 +95,6 @@ do {									\
 #endif				/* (WL_DBG_LEVEL > 0) */
 
 #define WL_SCAN_RETRY_MAX	3	/* used for ibss scan */
-#define WL_NUM_SCAN_MAX		1
 #define WL_NUM_PMKIDS_MAX	MAXPMKID	/* will be used
 						 * for 2.6.33 kernel
 						 * or later
@@ -188,14 +195,6 @@ struct wl_conf {
 typedef s32(*EVENT_HANDLER) (struct wl_priv *wl,
                             struct net_device *ndev, const wl_event_msg_t *e, void *data);
 
-/* representing interface of cfg80211 plane */
-struct wl_iface {
-	struct wl_priv *wl;
-};
-
-struct wl_dev {
-	void *driver_data;	/* to store cfg80211 object information */
-};
 
 /* bss inform structure for cfg80211 interface */
 struct wl_cfg80211_bss_info {
@@ -388,18 +387,11 @@ struct wl_priv {
 	struct p2p_info *p2p;
 	bool p2p_supported;
 	s8 last_eventmask[WL_EVENTING_MASK_LEN];
-	u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
 };
 
-#define wl_to_dev(w) (wiphy_dev(wl->wdev->wiphy))
 #define wl_to_wiphy(w) (w->wdev->wiphy)
-#define wiphy_to_wl(w) ((struct wl_priv *)(wiphy_priv(w)))
-#define wl_to_wdev(w) (w->wdev)
-#define wdev_to_wl(w) ((struct wl_priv *)(wdev_priv(w)))
 #define wl_to_prmry_ndev(w) (w->wdev->netdev)
 #define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
-#define ci_to_wl(c) (ci->wl)
-#define wl_to_ci(w) (&w->ci)
 #define wl_to_sr(w) (w->scan_req_int)
 #define wl_to_ie(w) (&w->ie)
 #define iscan_to_wl(i) ((struct wl_priv *)(i->data))
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index a261a72..3d7b548 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -970,8 +970,7 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
 	} while (0);
 
 	s32 ret = BCME_OK;
-	CFGP2P_DBG((" Enter\n"));
-	CFGP2P_INFO(("Channel : %d, Duration : %d\n", channel, duration_ms));
+	CFGP2P_DBG((" Enter Channel : %d, Duration : %d\n", channel, duration_ms));
 	if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) {
 
 		CFGP2P_ERR((" Discovery is not set, so we have noting to do\n"));
@@ -996,9 +995,9 @@ 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
+	 *  otherwise we will wait up to duration_ms + 200ms
 	 */
-	INIT_TIMER(wl->p2p->listen_timer, wl_cfgp2p_listen_expired, duration_ms, 20);
+	INIT_TIMER(wl->p2p->listen_timer, wl_cfgp2p_listen_expired, duration_ms, 200);
 
 #undef INIT_TIMER
 exit:
-- 
1.7.1


