]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/mac80211/scan.c
mac80211: disable moving between PS modes during scan
[karo-tx-linux.git] / net / mac80211 / scan.c
index c99ef8d04d3df6fc0e79588eed87526a74a6f34e..2a8d09ad17ff8829cc777143d0cff77dff6052c3 100644 (file)
@@ -298,6 +298,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
        was_hw_scan = local->hw_scanning;
        local->hw_scanning = false;
        local->sw_scanning = false;
+       local->scan_channel = NULL;
 
        /* we only have to protect scan_req and hw/sw scan */
        mutex_unlock(&local->scan_mtx);
@@ -558,24 +559,39 @@ void ieee80211_scan_work(struct work_struct *work)
                if (skip)
                        break;
 
-               next_delay = IEEE80211_PROBE_DELAY +
-                            usecs_to_jiffies(local->hw.channel_change_time);
+               /*
+                * Probe delay is used to update the NAV, cf. 11.1.3.2.2
+                * (which unfortunately doesn't say _why_ step a) is done,
+                * but it waits for the probe delay or until a frame is
+                * received - and the received frame would update the NAV).
+                * For now, we do not support waiting until a frame is
+                * received.
+                *
+                * In any case, it is not necessary for a passive scan.
+                */
+               if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
+                   !local->scan_req->n_ssids) {
+                       next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+                       break;
+               }
+
+               next_delay = IEEE80211_PROBE_DELAY;
                local->scan_state = SCAN_SEND_PROBE;
                break;
        case SCAN_SEND_PROBE:
-               next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
-               local->scan_state = SCAN_SET_CHANNEL;
-
-               if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
-                   !local->scan_req->n_ssids)
-                       break;
                for (i = 0; i < local->scan_req->n_ssids; i++)
                        ieee80211_send_probe_req(
                                sdata, NULL,
                                local->scan_req->ssids[i].ssid,
                                local->scan_req->ssids[i].ssid_len,
                                local->scan_req->ie, local->scan_req->ie_len);
+
+               /*
+                * After sending probe requests, wait for probe responses
+                * on the channel.
+                */
                next_delay = IEEE80211_CHANNEL_TIME;
+               local->scan_state = SCAN_SET_CHANNEL;
                break;
        }
 
@@ -615,3 +631,21 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
        mutex_unlock(&local->scan_mtx);
        return ret;
 }
+
+void ieee80211_scan_cancel(struct ieee80211_local *local)
+{
+       bool swscan;
+
+       cancel_delayed_work_sync(&local->scan_work);
+
+       /*
+        * Only call this function when a scan can't be
+        * queued -- mostly at suspend under RTNL.
+        */
+       mutex_lock(&local->scan_mtx);
+       swscan = local->sw_scanning;
+       mutex_unlock(&local->scan_mtx);
+
+       if (swscan)
+               ieee80211_scan_completed(&local->hw, true);
+}