Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / net / mac80211 / scan.c
index 669d2e3..08a45ac 100644 (file)
@@ -228,6 +228,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
 {
        struct cfg80211_scan_request *req = local->scan_req;
+       struct ieee80211_sub_if_data *sdata = local->scan_sdata;
        enum ieee80211_band band;
        int i, ielen, n_chans;
 
@@ -251,8 +252,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
        local->hw_scan_req->n_channels = n_chans;
 
        ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
-                                        req->ie, req->ie_len, band, (u32) -1,
-                                        0);
+                                        req->ie, req->ie_len, band,
+                                        sdata->rc_rateidx_mask[band], 0);
        local->hw_scan_req->ie_len = ielen;
 
        return true;
@@ -658,7 +659,8 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
                        sdata, NULL,
                        local->scan_req->ssids[i].ssid,
                        local->scan_req->ssids[i].ssid_len,
-                       local->scan_req->ie, local->scan_req->ie_len);
+                       local->scan_req->ie, local->scan_req->ie_len,
+                       false);
 
        /*
         * After sending probe requests, wait for probe responses
@@ -821,10 +823,8 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
  */
 void ieee80211_scan_cancel(struct ieee80211_local *local)
 {
-       bool abortscan;
-
        /*
-        * We are only canceling software scan, or deferred scan that was not
+        * We are canceling software scan, or deferred scan that was not
         * yet really started (see __ieee80211_start_scan ).
         *
         * Regarding hardware scan:
@@ -836,23 +836,30 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
         * - we can not cancel scan_work since driver can schedule it
         *   by ieee80211_scan_completed(..., true) to finish scan
         *
-        * Hence low lever driver is responsible for canceling HW scan.
+        * Hence we only call the cancel_hw_scan() callback, but the low-level
+        * driver is still responsible for calling ieee80211_scan_completed()
+        * after the scan was completed/aborted.
         */
 
        mutex_lock(&local->mtx);
-       abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
-       if (abortscan) {
-               /*
-                * The scan is canceled, but stop work from being pending.
-                *
-                * If the work is currently running, it must be blocked on
-                * the mutex, but we'll set scan_sdata = NULL and it'll
-                * simply exit once it acquires the mutex.
-                */
-               cancel_delayed_work(&local->scan_work);
-               /* and clean up */
-               __ieee80211_scan_completed(&local->hw, true, false);
+       if (!local->scan_req)
+               goto out;
+
+       if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
+               if (local->ops->cancel_hw_scan)
+                       drv_cancel_hw_scan(local, local->scan_sdata);
+               goto out;
        }
+
+       /*
+        * If the work is currently running, it must be blocked on
+        * the mutex, but we'll set scan_sdata = NULL and it'll
+        * simply exit once it acquires the mutex.
+        */
+       cancel_delayed_work(&local->scan_work);
+       /* and clean up */
+       __ieee80211_scan_completed(&local->hw, true, false);
+out:
        mutex_unlock(&local->mtx);
 }