mwifiex: abort scan upon interface down
authorAmitkumar Karwar <akarwar@marvell.com>
Sat, 20 Oct 2012 02:19:16 +0000 (19:19 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 29 Oct 2012 19:20:33 +0000 (15:20 -0400)
When the interface is down, we will abort scan by calling
cfg80211_scan_done() with abort option. This fixes WARN_ON
triggered by cfg80211 in wdev_cleanup_work().

Driver's internal variables/flags are cleared once we get
response for current scan command. Meanwhile we will block
new scan request from cfg80211.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/scan.c

index 60461325dff809deaa88f5279f2599ef49e76673..0a067bd0222f928c72e9ee79825898b15ed79260 100644 (file)
@@ -1828,6 +1828,11 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
 
        priv->scan_request = request;
 
+       if (priv->user_scan_cfg) {
+               dev_err(priv->adapter->dev, "cmd: Scan already in process..\n");
+               return -EBUSY;
+       }
+
        priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
                                      GFP_KERNEL);
        if (!priv->user_scan_cfg) {
index b5d37a8caa09a4429504fd804d8a6a5b1542b1af..37f2d957bbf02f508f68e7bad8dd654ab9db6315 100644 (file)
@@ -84,10 +84,16 @@ static void scan_delay_timer_fn(unsigned long data)
                spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
 
                if (priv->user_scan_cfg) {
-                       dev_dbg(priv->adapter->dev,
-                               "info: %s: scan aborted\n", __func__);
-                       cfg80211_scan_done(priv->scan_request, 1);
-                       priv->scan_request = NULL;
+                       if (priv->scan_request) {
+                               dev_dbg(priv->adapter->dev,
+                                       "info: aborting scan\n");
+                               cfg80211_scan_done(priv->scan_request, 1);
+                               priv->scan_request = NULL;
+                       } else {
+                               dev_dbg(priv->adapter->dev,
+                                       "info: scan already aborted\n");
+                       }
+
                        kfree(priv->user_scan_cfg);
                        priv->user_scan_cfg = NULL;
                }
index eb22dd248d5491e0644a7b60225216faeae7ad1a..1df767bc8b6eb1efd34f2cb655698caa26453146 100644 (file)
@@ -472,6 +472,14 @@ mwifiex_open(struct net_device *dev)
 static int
 mwifiex_close(struct net_device *dev)
 {
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+       if (priv->scan_request) {
+               dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n");
+               cfg80211_scan_done(priv->scan_request, 1);
+               priv->scan_request = NULL;
+       }
+
        return 0;
 }
 
index 05965267cc271c37440a0c993ae7d811120cfadf..32b79ddd774bbea37308b77031d1ebb8a3c5a16a 100644 (file)
@@ -1768,16 +1768,29 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                }
 
                if (priv->user_scan_cfg) {
-                       dev_dbg(priv->adapter->dev,
-                               "info: %s: sending scan results\n", __func__);
-                       cfg80211_scan_done(priv->scan_request, 0);
-                       priv->scan_request = NULL;
+                       if (priv->scan_request) {
+                               dev_dbg(priv->adapter->dev,
+                                       "info: notifying scan done\n");
+                               cfg80211_scan_done(priv->scan_request, 0);
+                               priv->scan_request = NULL;
+                       } else {
+                               dev_dbg(priv->adapter->dev,
+                                       "info: scan already aborted\n");
+                       }
+
                        kfree(priv->user_scan_cfg);
                        priv->user_scan_cfg = NULL;
                }
        } else {
-               if (!mwifiex_wmm_lists_empty(adapter) &&
-                   (priv->scan_request && (priv->scan_request->flags &
+               if (priv->user_scan_cfg && !priv->scan_request) {
+                       spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+                                              flags);
+                       adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
+                       mod_timer(&priv->scan_delay_timer, jiffies);
+                       dev_dbg(priv->adapter->dev,
+                               "info: %s: triggerring scan abort\n", __func__);
+               } else if (!mwifiex_wmm_lists_empty(adapter) &&
+                          (priv->scan_request && (priv->scan_request->flags &
                                            NL80211_SCAN_FLAG_LOW_PRIORITY))) {
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);