From 0635505f1a2c9e78d11a4d96b9605514c2c06344 Mon Sep 17 00:00:00 2001
From: Howard M. Harte <hharte@broadcom.com>
Date: Mon, 25 Jul 2011 19:46:20 -0700
Subject: [PATCH 509/696] Fix scan and connection problem.

Change-Id: Idd77caf358fc77c4b81929c644020d09009e4f36
Signed-off-by: Howard M. Harte <hharte@broadcom.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
---
 drivers/net/wireless/bcmdhd/wl_cfg80211.c |   40 +++++++++++++++++++++-------
 1 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index b83cb3e..d4ccff6 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -427,7 +427,7 @@ static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
  */
 static void wl_iscan_timer(unsigned long data);
 static void wl_term_iscan(struct wl_priv *wl);
-static s32 wl_init_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,
 	u16 action);
@@ -2068,8 +2068,20 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	size_t join_params_size;
 	s32 err = 0;
 
-	WL_TRACE(("In\n"));
+	WL_DBG(("In\n"));
 	CHECK_SYS_UP();
+
+	/*
+	 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
+	 */
+	if (wl->scan_request) {
+		wl_set_drv_status(wl, SCAN_ABORTING);
+		cfg80211_scan_done(wl->scan_request, true);
+		wl->scan_request = NULL;
+		wl_clr_drv_status(wl, SCANNING);
+		wl_clr_drv_status(wl, SCAN_ABORTING);
+	}
+
 	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 (p2p_on(wl) && is_wps_conn(sme)) {
@@ -2762,7 +2774,7 @@ static s32 wl_cfg80211_resume(struct wiphy *wiphy)
 	struct wl_priv *wl = WL_PRIV_GET();
 	s32 err = 0;
 
-	if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) {
+	if (unlikely(!wl_get_drv_status(wl, READY))) {
 		WL_INFO(("device is not ready : status (%d)\n",
 			(int)wl->status));
 		return 0;
@@ -2782,7 +2794,7 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
 	struct wl_priv *wl = WL_PRIV_GET();
 	s32 err = 0;
 
-	if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) {
+	if (unlikely(!wl_get_drv_status(wl, READY))) {
 		WL_INFO(("device is not ready : status (%d)\n",
 			(int)wl->status));
 		return 0;
@@ -4510,7 +4522,17 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
 			GFP_KERNEL);
 		WL_DBG(("Report roaming result\n"));
 	}
-	wl_set_drv_status(wl, CONNECTED);
+	if (completed)
+		wl_set_drv_status(wl, CONNECTED);
+	else {
+		if (wl->scan_request) {
+			wl_set_drv_status(wl, SCAN_ABORTING);
+			cfg80211_scan_done(wl->scan_request, true);
+			wl->scan_request = NULL;
+			wl_clr_drv_status(wl, SCANNING);
+			wl_clr_drv_status(wl, SCAN_ABORTING);
+		}
+	}
 
 	return err;
 }
@@ -4554,8 +4576,6 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
 		return -EINVAL;
 	}
 	wl_clr_drv_status(wl, SCANNING);
-	if (unlikely(!wl->scan_request)) {
-	}
 	rtnl_lock();
 	err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
 		sizeof(channel_inform), false);
@@ -4589,7 +4609,7 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
 
 scan_done_out:
 	if (wl->scan_request) {
-		WL_ERR(("cfg80211_scan_done\n"));
+		WL_DBG(("cfg80211_scan_done\n"));
 		cfg80211_scan_done(wl->scan_request, false);
 		wl->scan_request = NULL;
 	}
@@ -5192,7 +5212,7 @@ exit:
 	return err;
 }
 
-static s32 wl_init_iscan(struct wl_priv *wl)
+static s32 wl_init_scan(struct wl_priv *wl)
 {
 	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
 	int err = 0;
@@ -5254,7 +5274,7 @@ static s32 wl_init_priv(struct wl_priv *wl)
 		return -ENOMEM;
 	wl_init_event_handler(wl);
 	mutex_init(&wl->usr_sync);
-	err = wl_init_iscan(wl);
+	err = wl_init_scan(wl);
 	if (unlikely(err))
 		return err;
 	wl_init_fw(wl->fw);
-- 
1.7.1


