wifi: mac80211: Don't finalize CSA in IBSS mode if state is disconnected
[platform/kernel/linux-rpi.git] / net / mac80211 / scan.c
index 6b50cb5..887f945 100644 (file)
@@ -277,6 +277,16 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
        if (likely(!sdata1 && !sdata2))
                return;
 
+       if (test_and_clear_bit(SCAN_BEACON_WAIT, &local->scanning)) {
+               /*
+                * we were passive scanning because of radar/no-IR, but
+                * the beacon/proberesp rx gives us an opportunity to upgrade
+                * to active scan
+                */
+                set_bit(SCAN_BEACON_DONE, &local->scanning);
+                ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
+       }
+
        if (ieee80211_is_probe_resp(mgmt->frame_control)) {
                struct cfg80211_scan_request *scan_req;
                struct cfg80211_sched_scan_request *sched_scan_req;
@@ -783,6 +793,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
                                                IEEE80211_CHAN_RADAR)) ||
                    !req->n_ssids) {
                        next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+                       if (req->n_ssids)
+                               set_bit(SCAN_BEACON_WAIT, &local->scanning);
                } else {
                        ieee80211_scan_state_send_probe(local, &next_delay);
                        next_delay = IEEE80211_CHANNEL_TIME;
@@ -994,6 +1006,8 @@ set_channel:
            !scan_req->n_ssids) {
                *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
                local->next_scan_state = SCAN_DECISION;
+               if (scan_req->n_ssids)
+                       set_bit(SCAN_BEACON_WAIT, &local->scanning);
                return;
        }
 
@@ -1086,6 +1100,8 @@ void ieee80211_scan_work(struct work_struct *work)
                        goto out;
        }
 
+       clear_bit(SCAN_BEACON_WAIT, &local->scanning);
+
        /*
         * as long as no delay is required advance immediately
         * without scheduling a new work
@@ -1096,6 +1112,10 @@ void ieee80211_scan_work(struct work_struct *work)
                        goto out_complete;
                }
 
+               if (test_and_clear_bit(SCAN_BEACON_DONE, &local->scanning) &&
+                   local->next_scan_state == SCAN_DECISION)
+                       local->next_scan_state = SCAN_SEND_PROBE;
+
                switch (local->next_scan_state) {
                case SCAN_DECISION:
                        /* if no more bands/channels left, complete scan */