~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to net/mac80211/scan.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
170
170
                return RX_CONTINUE;
171
171
 
172
172
        if (skb->len < 24)
173
 
                return RX_DROP_MONITOR;
 
173
                return RX_CONTINUE;
174
174
 
175
175
        presp = ieee80211_is_probe_resp(fc);
176
176
        if (presp) {
196
196
        ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
197
197
 
198
198
        if (elems.ds_params && elems.ds_params_len == 1)
199
 
                freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
 
199
                freq = ieee80211_channel_to_frequency(elems.ds_params[0],
 
200
                                                      rx_status->band);
200
201
        else
201
202
                freq = rx_status->freq;
202
203
 
211
212
        if (bss)
212
213
                ieee80211_rx_bss_put(sdata->local, bss);
213
214
 
 
215
        /* If we are on-operating-channel, and this packet is for the
 
216
         * current channel, pass the pkt on up the stack so that
 
217
         * the rest of the stack can make use of it.
 
218
         */
 
219
        if (ieee80211_cfg_on_oper_channel(sdata->local)
 
220
            && (channel == sdata->local->oper_channel))
 
221
                return RX_CONTINUE;
 
222
 
214
223
        dev_kfree_skb(skb);
215
224
        return RX_QUEUED;
216
225
}
249
258
        return true;
250
259
}
251
260
 
252
 
static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
 
261
static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
253
262
                                       bool was_hw_scan)
254
263
{
255
264
        struct ieee80211_local *local = hw_to_local(hw);
 
265
        bool on_oper_chan;
 
266
        bool enable_beacons = false;
256
267
 
257
268
        lockdep_assert_held(&local->mtx);
258
269
 
266
277
                aborted = true;
267
278
 
268
279
        if (WARN_ON(!local->scan_req))
269
 
                return false;
 
280
                return;
270
281
 
271
282
        if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
272
283
                int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req);
273
284
                if (rc == 0)
274
 
                        return false;
 
285
                        return;
275
286
        }
276
287
 
277
288
        kfree(local->hw_scan_req);
285
296
        local->scanning = 0;
286
297
        local->scan_channel = NULL;
287
298
 
288
 
        return true;
289
 
}
290
 
 
291
 
static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw,
292
 
                                              bool was_hw_scan)
293
 
{
294
 
        struct ieee80211_local *local = hw_to_local(hw);
295
 
 
296
 
        ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
299
        on_oper_chan = ieee80211_cfg_on_oper_channel(local);
 
300
 
 
301
        if (was_hw_scan || !on_oper_chan)
 
302
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
303
        else
 
304
                /* Set power back to normal operating levels. */
 
305
                ieee80211_hw_config(local, 0);
 
306
 
297
307
        if (!was_hw_scan) {
 
308
                bool on_oper_chan2;
298
309
                ieee80211_configure_filter(local);
299
310
                drv_sw_scan_complete(local);
300
 
                ieee80211_offchannel_return(local, true);
 
311
                on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
 
312
                /* We should always be on-channel at this point. */
 
313
                WARN_ON(!on_oper_chan2);
 
314
                if (on_oper_chan2 && (on_oper_chan != on_oper_chan2))
 
315
                        enable_beacons = true;
 
316
 
 
317
                ieee80211_offchannel_return(local, enable_beacons, true);
301
318
        }
302
319
 
303
 
        mutex_lock(&local->mtx);
304
320
        ieee80211_recalc_idle(local);
305
 
        mutex_unlock(&local->mtx);
306
321
 
307
322
        ieee80211_mlme_notify_scan_completed(local);
308
323
        ieee80211_ibss_notify_scan_completed(local);
340
355
         */
341
356
        drv_sw_scan_start(local);
342
357
 
343
 
        ieee80211_offchannel_stop_beaconing(local);
344
 
 
345
358
        local->leave_oper_channel_time = 0;
346
359
        local->next_scan_state = SCAN_DECISION;
347
360
        local->scan_channel_idx = 0;
348
361
 
349
 
        drv_flush(local, false);
 
362
        /* We always want to use off-channel PS, even if we
 
363
         * are not really leaving oper-channel.  Don't
 
364
         * tell the AP though, as long as we are on-channel.
 
365
         */
 
366
        ieee80211_offchannel_enable_all_ps(local, false);
350
367
 
351
368
        ieee80211_configure_filter(local);
352
369
 
 
370
        /* We need to set power level at maximum rate for scanning. */
 
371
        ieee80211_hw_config(local, 0);
 
372
 
353
373
        ieee80211_queue_delayed_work(&local->hw,
354
374
                                     &local->scan_work,
355
375
                                     IEEE80211_CHANNEL_TIME);
486
506
        }
487
507
        mutex_unlock(&local->iflist_mtx);
488
508
 
489
 
        if (local->scan_channel) {
 
509
        next_chan = local->scan_req->channels[local->scan_channel_idx];
 
510
 
 
511
        if (ieee80211_cfg_on_oper_channel(local)) {
 
512
                /* We're currently on operating channel. */
 
513
                if (next_chan == local->oper_channel)
 
514
                        /* We don't need to move off of operating channel. */
 
515
                        local->next_scan_state = SCAN_SET_CHANNEL;
 
516
                else
 
517
                        /*
 
518
                         * We do need to leave operating channel, as next
 
519
                         * scan is somewhere else.
 
520
                         */
 
521
                        local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
 
522
        } else {
490
523
                /*
491
524
                 * we're currently scanning a different channel, let's
492
525
                 * see if we can scan another channel without interfering
502
535
                 *
503
536
                 * Otherwise switch back to the operating channel.
504
537
                 */
505
 
                next_chan = local->scan_req->channels[local->scan_channel_idx];
506
538
 
507
539
                bad_latency = time_after(jiffies +
508
540
                                ieee80211_scan_get_channel_time(next_chan),
520
552
                        local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
521
553
                else
522
554
                        local->next_scan_state = SCAN_SET_CHANNEL;
523
 
        } else {
524
 
                /*
525
 
                 * we're on the operating channel currently, let's
526
 
                 * leave that channel now to scan another one
527
 
                 */
528
 
                local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
529
555
        }
530
556
 
531
557
        *next_delay = 0;
534
560
static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
535
561
                                                    unsigned long *next_delay)
536
562
{
537
 
        ieee80211_offchannel_stop_station(local);
538
 
 
539
 
        __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
 
563
        /* PS will already be in off-channel mode,
 
564
         * we do that once at the beginning of scanning.
 
565
         */
 
566
        ieee80211_offchannel_stop_vifs(local, false);
540
567
 
541
568
        /*
542
569
         * What if the nullfunc frames didn't arrive?
559
586
{
560
587
        /* switch back to the operating channel */
561
588
        local->scan_channel = NULL;
562
 
        ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
589
        if (!ieee80211_cfg_on_oper_channel(local))
 
590
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
563
591
 
564
592
        /*
565
 
         * Only re-enable station mode interface now; beaconing will be
566
 
         * re-enabled once the full scan has been completed.
 
593
         * Re-enable vifs and beaconing.  Leave PS
 
594
         * in off-channel state..will put that back
 
595
         * on-channel at the end of scanning.
567
596
         */
568
 
        ieee80211_offchannel_return(local, false);
569
 
 
570
 
        __clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
 
597
        ieee80211_offchannel_return(local, true, false);
571
598
 
572
599
        *next_delay = HZ / 5;
573
600
        local->next_scan_state = SCAN_DECISION;
583
610
        chan = local->scan_req->channels[local->scan_channel_idx];
584
611
 
585
612
        local->scan_channel = chan;
586
 
        if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
587
 
                skip = 1;
 
613
 
 
614
        /* Only call hw-config if we really need to change channels. */
 
615
        if (chan != local->hw.conf.channel)
 
616
                if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
 
617
                        skip = 1;
588
618
 
589
619
        /* advance state machine to next channel/band */
590
620
        local->scan_channel_idx++;
642
672
{
643
673
        struct ieee80211_local *local =
644
674
                container_of(work, struct ieee80211_local, scan_work.work);
645
 
        struct ieee80211_sub_if_data *sdata = local->scan_sdata;
 
675
        struct ieee80211_sub_if_data *sdata;
646
676
        unsigned long next_delay = 0;
647
 
        bool aborted, hw_scan, finish;
 
677
        bool aborted, hw_scan;
648
678
 
649
679
        mutex_lock(&local->mtx);
650
680
 
 
681
        sdata = local->scan_sdata;
 
682
 
651
683
        if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
652
684
                aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
653
685
                goto out_complete;
686
718
         * without scheduling a new work
687
719
         */
688
720
        do {
 
721
                if (!ieee80211_sdata_running(sdata)) {
 
722
                        aborted = true;
 
723
                        goto out_complete;
 
724
                }
 
725
 
689
726
                switch (local->next_scan_state) {
690
727
                case SCAN_DECISION:
691
728
                        /* if no more bands/channels left, complete scan */
711
748
        } while (next_delay == 0);
712
749
 
713
750
        ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
714
 
        mutex_unlock(&local->mtx);
715
 
        return;
 
751
        goto out;
716
752
 
717
753
out_complete:
718
754
        hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
719
 
        finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
720
 
        mutex_unlock(&local->mtx);
721
 
        if (finish)
722
 
                __ieee80211_scan_completed_finish(&local->hw, hw_scan);
723
 
        return;
724
 
 
 
755
        __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
725
756
out:
726
757
        mutex_unlock(&local->mtx);
727
758
}
791
822
void ieee80211_scan_cancel(struct ieee80211_local *local)
792
823
{
793
824
        bool abortscan;
794
 
        bool finish = false;
795
825
 
796
826
        /*
797
827
         * We are only canceling software scan, or deferred scan that was not
811
841
 
812
842
        mutex_lock(&local->mtx);
813
843
        abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
814
 
        if (abortscan)
815
 
                finish = __ieee80211_scan_completed(&local->hw, true, false);
816
 
        mutex_unlock(&local->mtx);
817
 
 
818
844
        if (abortscan) {
819
 
                /* The scan is canceled, but stop work from being pending */
820
 
                cancel_delayed_work_sync(&local->scan_work);
821
 
        }
822
 
        if (finish)
823
 
                __ieee80211_scan_completed_finish(&local->hw, false);
824
 
}
 
845
                /*
 
846
                 * The scan is canceled, but stop work from being pending.
 
847
                 *
 
848
                 * If the work is currently running, it must be blocked on
 
849
                 * the mutex, but we'll set scan_sdata = NULL and it'll
 
850
                 * simply exit once it acquires the mutex.
 
851
                 */
 
852
                cancel_delayed_work(&local->scan_work);
 
853
                /* and clean up */
 
854
                __ieee80211_scan_completed(&local->hw, true, false);
 
855
        }
 
856
        mutex_unlock(&local->mtx);
 
857
}
 
858
 
 
859
int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
 
860
                                       struct cfg80211_sched_scan_request *req)
 
861
{
 
862
        struct ieee80211_local *local = sdata->local;
 
863
        int ret, i;
 
864
 
 
865
        mutex_lock(&sdata->local->mtx);
 
866
 
 
867
        if (local->sched_scanning) {
 
868
                ret = -EBUSY;
 
869
                goto out;
 
870
        }
 
871
 
 
872
        if (!local->ops->sched_scan_start) {
 
873
                ret = -ENOTSUPP;
 
874
                goto out;
 
875
        }
 
876
 
 
877
        for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
 
878
                local->sched_scan_ies.ie[i] = kzalloc(2 +
 
879
                                                      IEEE80211_MAX_SSID_LEN +
 
880
                                                      local->scan_ies_len +
 
881
                                                      req->ie_len,
 
882
                                                      GFP_KERNEL);
 
883
                if (!local->sched_scan_ies.ie[i]) {
 
884
                        ret = -ENOMEM;
 
885
                        goto out_free;
 
886
                }
 
887
 
 
888
                local->sched_scan_ies.len[i] =
 
889
                        ieee80211_build_preq_ies(local,
 
890
                                                 local->sched_scan_ies.ie[i],
 
891
                                                 req->ie, req->ie_len, i,
 
892
                                                 (u32) -1, 0);
 
893
        }
 
894
 
 
895
        ret = drv_sched_scan_start(local, sdata, req,
 
896
                                   &local->sched_scan_ies);
 
897
        if (ret == 0) {
 
898
                local->sched_scanning = true;
 
899
                goto out;
 
900
        }
 
901
 
 
902
out_free:
 
903
        while (i > 0)
 
904
                kfree(local->sched_scan_ies.ie[--i]);
 
905
out:
 
906
        mutex_unlock(&sdata->local->mtx);
 
907
        return ret;
 
908
}
 
909
 
 
910
int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
 
911
{
 
912
        struct ieee80211_local *local = sdata->local;
 
913
        int ret = 0, i;
 
914
 
 
915
        mutex_lock(&sdata->local->mtx);
 
916
 
 
917
        if (!local->ops->sched_scan_stop) {
 
918
                ret = -ENOTSUPP;
 
919
                goto out;
 
920
        }
 
921
 
 
922
        if (local->sched_scanning) {
 
923
                for (i = 0; i < IEEE80211_NUM_BANDS; i++)
 
924
                        kfree(local->sched_scan_ies.ie[i]);
 
925
 
 
926
                drv_sched_scan_stop(local, sdata);
 
927
                local->sched_scanning = false;
 
928
        }
 
929
out:
 
930
        mutex_unlock(&sdata->local->mtx);
 
931
 
 
932
        return ret;
 
933
}
 
934
 
 
935
void ieee80211_sched_scan_results(struct ieee80211_hw *hw)
 
936
{
 
937
        struct ieee80211_local *local = hw_to_local(hw);
 
938
 
 
939
        trace_api_sched_scan_results(local);
 
940
 
 
941
        cfg80211_sched_scan_results(hw->wiphy);
 
942
}
 
943
EXPORT_SYMBOL(ieee80211_sched_scan_results);
 
944
 
 
945
void ieee80211_sched_scan_stopped_work(struct work_struct *work)
 
946
{
 
947
        struct ieee80211_local *local =
 
948
                container_of(work, struct ieee80211_local,
 
949
                             sched_scan_stopped_work);
 
950
        int i;
 
951
 
 
952
        mutex_lock(&local->mtx);
 
953
 
 
954
        if (!local->sched_scanning) {
 
955
                mutex_unlock(&local->mtx);
 
956
                return;
 
957
        }
 
958
 
 
959
        for (i = 0; i < IEEE80211_NUM_BANDS; i++)
 
960
                kfree(local->sched_scan_ies.ie[i]);
 
961
 
 
962
        local->sched_scanning = false;
 
963
 
 
964
        mutex_unlock(&local->mtx);
 
965
 
 
966
        cfg80211_sched_scan_stopped(local->hw.wiphy);
 
967
}
 
968
 
 
969
void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
 
970
{
 
971
        struct ieee80211_local *local = hw_to_local(hw);
 
972
 
 
973
        trace_api_sched_scan_stopped(local);
 
974
 
 
975
        ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work);
 
976
}
 
977
EXPORT_SYMBOL(ieee80211_sched_scan_stopped);