scan.c (1b0db64fb7693c1a131b7bcc38f7bc63fb396850) scan.c (d07bfd8b6f20a81d7ec65c50f35b053d9e3aa740)
1/*
2 * Scanning implementation
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2004, Instant802 Networks, Inc.
6 * Copyright 2005, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>

--- 244 unchanged lines hidden (view full) ---

253 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
254 req->ie, req->ie_len, band, (u32) -1,
255 0);
256 local->hw_scan_req->ie_len = ielen;
257
258 return true;
259}
260
1/*
2 * Scanning implementation
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2004, Instant802 Networks, Inc.
6 * Copyright 2005, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>

--- 244 unchanged lines hidden (view full) ---

253 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
254 req->ie, req->ie_len, band, (u32) -1,
255 0);
256 local->hw_scan_req->ie_len = ielen;
257
258 return true;
259}
260
261static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
261static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
262 bool was_hw_scan)
263{
264 struct ieee80211_local *local = hw_to_local(hw);
262 bool was_hw_scan)
263{
264 struct ieee80211_local *local = hw_to_local(hw);
265 bool on_oper_chan;
266 bool enable_beacons = false;
265
266 lockdep_assert_held(&local->mtx);
267
268 /*
269 * It's ok to abort a not-yet-running scan (that
270 * we have one at all will be verified by checking
271 * local->scan_req next), but not to complete it
272 * successfully.
273 */
274 if (WARN_ON(!local->scanning && !aborted))
275 aborted = true;
276
277 if (WARN_ON(!local->scan_req))
267
268 lockdep_assert_held(&local->mtx);
269
270 /*
271 * It's ok to abort a not-yet-running scan (that
272 * we have one at all will be verified by checking
273 * local->scan_req next), but not to complete it
274 * successfully.
275 */
276 if (WARN_ON(!local->scanning && !aborted))
277 aborted = true;
278
279 if (WARN_ON(!local->scan_req))
278 return false;
280 return;
279
280 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
281 int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req);
282 if (rc == 0)
281
282 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
283 int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req);
284 if (rc == 0)
283 return false;
285 return;
284 }
285
286 kfree(local->hw_scan_req);
287 local->hw_scan_req = NULL;
288
289 if (local->scan_req != local->int_scan_req)
290 cfg80211_scan_done(local->scan_req, aborted);
291 local->scan_req = NULL;
292 local->scan_sdata = NULL;
293
294 local->scanning = 0;
295 local->scan_channel = NULL;
296
286 }
287
288 kfree(local->hw_scan_req);
289 local->hw_scan_req = NULL;
290
291 if (local->scan_req != local->int_scan_req)
292 cfg80211_scan_done(local->scan_req, aborted);
293 local->scan_req = NULL;
294 local->scan_sdata = NULL;
295
296 local->scanning = 0;
297 local->scan_channel = NULL;
298
297 return true;
298}
299
300static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw,
301 bool was_hw_scan)
302{
303 struct ieee80211_local *local = hw_to_local(hw);
304 bool on_oper_chan;
305 bool enable_beacons = false;
306
307 mutex_lock(&local->mtx);
308 on_oper_chan = ieee80211_cfg_on_oper_channel(local);
309
299 on_oper_chan = ieee80211_cfg_on_oper_channel(local);
300
310 WARN_ON(local->scanning & (SCAN_SW_SCANNING | SCAN_HW_SCANNING));
311
312 if (was_hw_scan || !on_oper_chan) {
313 if (WARN_ON(local->scan_channel))
314 local->scan_channel = NULL;
301 if (was_hw_scan || !on_oper_chan)
315 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
302 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
316 } else
303 else
317 /* Set power back to normal operating levels. */
318 ieee80211_hw_config(local, 0);
319
320 if (!was_hw_scan) {
321 bool on_oper_chan2;
322 ieee80211_configure_filter(local);
323 drv_sw_scan_complete(local);
324 on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
325 /* We should always be on-channel at this point. */
326 WARN_ON(!on_oper_chan2);
327 if (on_oper_chan2 && (on_oper_chan != on_oper_chan2))
328 enable_beacons = true;
329
330 ieee80211_offchannel_return(local, enable_beacons, true);
331 }
332
333 ieee80211_recalc_idle(local);
304 /* Set power back to normal operating levels. */
305 ieee80211_hw_config(local, 0);
306
307 if (!was_hw_scan) {
308 bool on_oper_chan2;
309 ieee80211_configure_filter(local);
310 drv_sw_scan_complete(local);
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);
318 }
319
320 ieee80211_recalc_idle(local);
334 mutex_unlock(&local->mtx);
335
336 ieee80211_mlme_notify_scan_completed(local);
337 ieee80211_ibss_notify_scan_completed(local);
338 ieee80211_mesh_notify_scan_completed(local);
339 ieee80211_queue_work(&local->hw, &local->work_work);
340}
341
342void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)

--- 338 unchanged lines hidden (view full) ---

681 *next_delay = IEEE80211_CHANNEL_TIME;
682 local->next_scan_state = SCAN_DECISION;
683}
684
685void ieee80211_scan_work(struct work_struct *work)
686{
687 struct ieee80211_local *local =
688 container_of(work, struct ieee80211_local, scan_work.work);
321
322 ieee80211_mlme_notify_scan_completed(local);
323 ieee80211_ibss_notify_scan_completed(local);
324 ieee80211_mesh_notify_scan_completed(local);
325 ieee80211_queue_work(&local->hw, &local->work_work);
326}
327
328void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)

--- 338 unchanged lines hidden (view full) ---

667 *next_delay = IEEE80211_CHANNEL_TIME;
668 local->next_scan_state = SCAN_DECISION;
669}
670
671void ieee80211_scan_work(struct work_struct *work)
672{
673 struct ieee80211_local *local =
674 container_of(work, struct ieee80211_local, scan_work.work);
689 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
675 struct ieee80211_sub_if_data *sdata;
690 unsigned long next_delay = 0;
676 unsigned long next_delay = 0;
691 bool aborted, hw_scan, finish;
677 bool aborted, hw_scan;
692
693 mutex_lock(&local->mtx);
694
678
679 mutex_lock(&local->mtx);
680
681 sdata = local->scan_sdata;
682
695 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
696 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
697 goto out_complete;
698 }
699
700 if (!sdata || !local->scan_req)
701 goto out;
702

--- 47 unchanged lines hidden (view full) ---

750 break;
751 case SCAN_ENTER_OPER_CHANNEL:
752 ieee80211_scan_state_enter_oper_channel(local, &next_delay);
753 break;
754 }
755 } while (next_delay == 0);
756
757 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
683 if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
684 aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
685 goto out_complete;
686 }
687
688 if (!sdata || !local->scan_req)
689 goto out;
690

--- 47 unchanged lines hidden (view full) ---

738 break;
739 case SCAN_ENTER_OPER_CHANNEL:
740 ieee80211_scan_state_enter_oper_channel(local, &next_delay);
741 break;
742 }
743 } while (next_delay == 0);
744
745 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
758 mutex_unlock(&local->mtx);
759 return;
746 goto out;
760
761out_complete:
762 hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
747
748out_complete:
749 hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
763 finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
764 mutex_unlock(&local->mtx);
765 if (finish)
766 __ieee80211_scan_completed_finish(&local->hw, hw_scan);
767 return;
768
750 __ieee80211_scan_completed(&local->hw, aborted, hw_scan);
769out:
770 mutex_unlock(&local->mtx);
771}
772
773int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
774 struct cfg80211_scan_request *req)
775{
776 int res;

--- 53 unchanged lines hidden (view full) ---

830}
831
832/*
833 * Only call this function when a scan can't be queued -- under RTNL.
834 */
835void ieee80211_scan_cancel(struct ieee80211_local *local)
836{
837 bool abortscan;
751out:
752 mutex_unlock(&local->mtx);
753}
754
755int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
756 struct cfg80211_scan_request *req)
757{
758 int res;

--- 53 unchanged lines hidden (view full) ---

812}
813
814/*
815 * Only call this function when a scan can't be queued -- under RTNL.
816 */
817void ieee80211_scan_cancel(struct ieee80211_local *local)
818{
819 bool abortscan;
838 bool finish = false;
839
840 /*
841 * We are only canceling software scan, or deferred scan that was not
842 * yet really started (see __ieee80211_start_scan ).
843 *
844 * Regarding hardware scan:
845 * - we can not call __ieee80211_scan_completed() as when
846 * SCAN_HW_SCANNING bit is set this function change
847 * local->hw_scan_req to operate on 5G band, what race with
848 * driver which can use local->hw_scan_req
849 *
850 * - we can not cancel scan_work since driver can schedule it
851 * by ieee80211_scan_completed(..., true) to finish scan
852 *
853 * Hence low lever driver is responsible for canceling HW scan.
854 */
855
856 mutex_lock(&local->mtx);
857 abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
820
821 /*
822 * We are only canceling software scan, or deferred scan that was not
823 * yet really started (see __ieee80211_start_scan ).
824 *
825 * Regarding hardware scan:
826 * - we can not call __ieee80211_scan_completed() as when
827 * SCAN_HW_SCANNING bit is set this function change
828 * local->hw_scan_req to operate on 5G band, what race with
829 * driver which can use local->hw_scan_req
830 *
831 * - we can not cancel scan_work since driver can schedule it
832 * by ieee80211_scan_completed(..., true) to finish scan
833 *
834 * Hence low lever driver is responsible for canceling HW scan.
835 */
836
837 mutex_lock(&local->mtx);
838 abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
858 if (abortscan)
859 finish = __ieee80211_scan_completed(&local->hw, true, false);
860 mutex_unlock(&local->mtx);
861
862 if (abortscan) {
839 if (abortscan) {
863 /* The scan is canceled, but stop work from being pending */
864 cancel_delayed_work_sync(&local->scan_work);
840 /*
841 * The scan is canceled, but stop work from being pending.
842 *
843 * If the work is currently running, it must be blocked on
844 * the mutex, but we'll set scan_sdata = NULL and it'll
845 * simply exit once it acquires the mutex.
846 */
847 cancel_delayed_work(&local->scan_work);
848 /* and clean up */
849 __ieee80211_scan_completed(&local->hw, true, false);
865 }
850 }
866 if (finish)
867 __ieee80211_scan_completed_finish(&local->hw, false);
851 mutex_unlock(&local->mtx);
868}
852}