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} |