aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c136
1 files changed, 56 insertions, 80 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8ed83dcc149f..43a45cf00e06 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -27,22 +27,15 @@
27 27
28#define IEEE80211_PROBE_DELAY (HZ / 33) 28#define IEEE80211_PROBE_DELAY (HZ / 33)
29#define IEEE80211_CHANNEL_TIME (HZ / 33) 29#define IEEE80211_CHANNEL_TIME (HZ / 33)
30#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 8) 30#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 9)
31
32static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
33{
34 struct ieee80211_bss *bss = (void *)cbss->priv;
35
36 kfree(bss_mesh_id(bss));
37 kfree(bss_mesh_cfg(bss));
38}
39 31
40void ieee80211_rx_bss_put(struct ieee80211_local *local, 32void ieee80211_rx_bss_put(struct ieee80211_local *local,
41 struct ieee80211_bss *bss) 33 struct ieee80211_bss *bss)
42{ 34{
43 if (!bss) 35 if (!bss)
44 return; 36 return;
45 cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv)); 37 cfg80211_put_bss(local->hw.wiphy,
38 container_of((void *)bss, struct cfg80211_bss, priv));
46} 39}
47 40
48static bool is_uapsd_supported(struct ieee802_11_elems *elems) 41static bool is_uapsd_supported(struct ieee802_11_elems *elems)
@@ -65,12 +58,11 @@ static bool is_uapsd_supported(struct ieee802_11_elems *elems)
65struct ieee80211_bss * 58struct ieee80211_bss *
66ieee80211_bss_info_update(struct ieee80211_local *local, 59ieee80211_bss_info_update(struct ieee80211_local *local,
67 struct ieee80211_rx_status *rx_status, 60 struct ieee80211_rx_status *rx_status,
68 struct ieee80211_mgmt *mgmt, 61 struct ieee80211_mgmt *mgmt, size_t len,
69 size_t len,
70 struct ieee802_11_elems *elems, 62 struct ieee802_11_elems *elems,
71 struct ieee80211_channel *channel, 63 struct ieee80211_channel *channel)
72 bool beacon)
73{ 64{
65 bool beacon = ieee80211_is_beacon(mgmt->frame_control);
74 struct cfg80211_bss *cbss; 66 struct cfg80211_bss *cbss;
75 struct ieee80211_bss *bss; 67 struct ieee80211_bss *bss;
76 int clen, srlen; 68 int clen, srlen;
@@ -86,10 +78,12 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
86 if (!cbss) 78 if (!cbss)
87 return NULL; 79 return NULL;
88 80
89 cbss->free_priv = ieee80211_rx_bss_free;
90 bss = (void *)cbss->priv; 81 bss = (void *)cbss->priv;
91 82
92 bss->device_ts = rx_status->device_timestamp; 83 if (beacon)
84 bss->device_ts_beacon = rx_status->device_timestamp;
85 else
86 bss->device_ts_presp = rx_status->device_timestamp;
93 87
94 if (elems->parse_error) { 88 if (elems->parse_error) {
95 if (beacon) 89 if (beacon)
@@ -113,18 +107,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
113 bss->valid_data |= IEEE80211_BSS_VALID_ERP; 107 bss->valid_data |= IEEE80211_BSS_VALID_ERP;
114 } 108 }
115 109
116 if (elems->tim && (!elems->parse_error ||
117 !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) {
118 struct ieee80211_tim_ie *tim_ie = elems->tim;
119 bss->dtim_period = tim_ie->dtim_period;
120 if (!elems->parse_error)
121 bss->valid_data |= IEEE80211_BSS_VALID_DTIM;
122 }
123
124 /* If the beacon had no TIM IE, or it was invalid, use 1 */
125 if (beacon && !bss->dtim_period)
126 bss->dtim_period = 1;
127
128 /* replace old supported rates if we get new values */ 110 /* replace old supported rates if we get new values */
129 if (!elems->parse_error || 111 if (!elems->parse_error ||
130 !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) { 112 !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) {
@@ -159,9 +141,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
159 bss->valid_data |= IEEE80211_BSS_VALID_WMM; 141 bss->valid_data |= IEEE80211_BSS_VALID_WMM;
160 } 142 }
161 143
162 if (!beacon)
163 bss->last_probe_resp = jiffies;
164
165 return bss; 144 return bss;
166} 145}
167 146
@@ -215,7 +194,7 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
215 194
216 bss = ieee80211_bss_info_update(local, rx_status, 195 bss = ieee80211_bss_info_update(local, rx_status,
217 mgmt, skb->len, &elems, 196 mgmt, skb->len, &elems,
218 channel, beacon); 197 channel);
219 if (bss) 198 if (bss)
220 ieee80211_rx_bss_put(local, bss); 199 ieee80211_rx_bss_put(local, bss);
221} 200}
@@ -304,7 +283,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
304 if (!was_hw_scan) { 283 if (!was_hw_scan) {
305 ieee80211_configure_filter(local); 284 ieee80211_configure_filter(local);
306 drv_sw_scan_complete(local); 285 drv_sw_scan_complete(local);
307 ieee80211_offchannel_return(local, true); 286 ieee80211_offchannel_return(local);
308 } 287 }
309 288
310 ieee80211_recalc_idle(local); 289 ieee80211_recalc_idle(local);
@@ -353,7 +332,10 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
353 local->next_scan_state = SCAN_DECISION; 332 local->next_scan_state = SCAN_DECISION;
354 local->scan_channel_idx = 0; 333 local->scan_channel_idx = 0;
355 334
356 ieee80211_offchannel_stop_vifs(local, true); 335 ieee80211_offchannel_stop_vifs(local);
336
337 /* ensure nullfunc is transmitted before leaving operating channel */
338 drv_flush(local, false);
357 339
358 ieee80211_configure_filter(local); 340 ieee80211_configure_filter(local);
359 341
@@ -369,6 +351,9 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
369static bool ieee80211_can_scan(struct ieee80211_local *local, 351static bool ieee80211_can_scan(struct ieee80211_local *local,
370 struct ieee80211_sub_if_data *sdata) 352 struct ieee80211_sub_if_data *sdata)
371{ 353{
354 if (local->radar_detect_enabled)
355 return false;
356
372 if (!list_empty(&local->roc_list)) 357 if (!list_empty(&local->roc_list))
373 return false; 358 return false;
374 359
@@ -403,6 +388,11 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
403 int i; 388 int i;
404 struct ieee80211_sub_if_data *sdata; 389 struct ieee80211_sub_if_data *sdata;
405 enum ieee80211_band band = local->hw.conf.channel->band; 390 enum ieee80211_band band = local->hw.conf.channel->band;
391 u32 tx_flags;
392
393 tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
394 if (local->scan_req->no_cck)
395 tx_flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
406 396
407 sdata = rcu_dereference_protected(local->scan_sdata, 397 sdata = rcu_dereference_protected(local->scan_sdata,
408 lockdep_is_held(&local->mtx)); 398 lockdep_is_held(&local->mtx));
@@ -414,8 +404,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
414 local->scan_req->ssids[i].ssid_len, 404 local->scan_req->ssids[i].ssid_len,
415 local->scan_req->ie, local->scan_req->ie_len, 405 local->scan_req->ie, local->scan_req->ie_len,
416 local->scan_req->rates[band], false, 406 local->scan_req->rates[band], false,
417 local->scan_req->no_cck, 407 tx_flags, local->hw.conf.channel, true);
418 local->hw.conf.channel, true);
419 408
420 /* 409 /*
421 * After sending probe requests, wait for probe responses 410 * After sending probe requests, wait for probe responses
@@ -559,8 +548,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
559 bool associated = false; 548 bool associated = false;
560 bool tx_empty = true; 549 bool tx_empty = true;
561 bool bad_latency; 550 bool bad_latency;
562 bool listen_int_exceeded;
563 unsigned long min_beacon_int = 0;
564 struct ieee80211_sub_if_data *sdata; 551 struct ieee80211_sub_if_data *sdata;
565 struct ieee80211_channel *next_chan; 552 struct ieee80211_channel *next_chan;
566 enum mac80211_scan_state next_scan_state; 553 enum mac80211_scan_state next_scan_state;
@@ -579,11 +566,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
579 if (sdata->u.mgd.associated) { 566 if (sdata->u.mgd.associated) {
580 associated = true; 567 associated = true;
581 568
582 if (sdata->vif.bss_conf.beacon_int <
583 min_beacon_int || min_beacon_int == 0)
584 min_beacon_int =
585 sdata->vif.bss_conf.beacon_int;
586
587 if (!qdisc_all_tx_empty(sdata->dev)) { 569 if (!qdisc_all_tx_empty(sdata->dev)) {
588 tx_empty = false; 570 tx_empty = false;
589 break; 571 break;
@@ -600,34 +582,19 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
600 * see if we can scan another channel without interfering 582 * see if we can scan another channel without interfering
601 * with the current traffic situation. 583 * with the current traffic situation.
602 * 584 *
603 * Since we don't know if the AP has pending frames for us 585 * Keep good latency, do not stay off-channel more than 125 ms.
604 * we can only check for our tx queues and use the current
605 * pm_qos requirements for rx. Hence, if no tx traffic occurs
606 * at all we will scan as many channels in a row as the pm_qos
607 * latency allows us to. Additionally we also check for the
608 * currently negotiated listen interval to prevent losing
609 * frames unnecessarily.
610 *
611 * Otherwise switch back to the operating channel.
612 */ 586 */
613 587
614 bad_latency = time_after(jiffies + 588 bad_latency = time_after(jiffies +
615 ieee80211_scan_get_channel_time(next_chan), 589 ieee80211_scan_get_channel_time(next_chan),
616 local->leave_oper_channel_time + 590 local->leave_oper_channel_time + HZ / 8);
617 usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY)));
618
619 listen_int_exceeded = time_after(jiffies +
620 ieee80211_scan_get_channel_time(next_chan),
621 local->leave_oper_channel_time +
622 usecs_to_jiffies(min_beacon_int * 1024) *
623 local->hw.conf.listen_interval);
624 591
625 if (associated && !tx_empty) { 592 if (associated && !tx_empty) {
626 if (local->scan_req->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) 593 if (local->scan_req->flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
627 next_scan_state = SCAN_ABORT; 594 next_scan_state = SCAN_ABORT;
628 else 595 else
629 next_scan_state = SCAN_SUSPEND; 596 next_scan_state = SCAN_SUSPEND;
630 } else if (associated && (bad_latency || listen_int_exceeded)) { 597 } else if (associated && bad_latency) {
631 next_scan_state = SCAN_SUSPEND; 598 next_scan_state = SCAN_SUSPEND;
632 } else { 599 } else {
633 next_scan_state = SCAN_SET_CHANNEL; 600 next_scan_state = SCAN_SET_CHANNEL;
@@ -690,12 +657,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
690 local->scan_channel = NULL; 657 local->scan_channel = NULL;
691 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 658 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
692 659
693 /* 660 /* disable PS */
694 * Re-enable vifs and beaconing. Leave PS 661 ieee80211_offchannel_return(local);
695 * in off-channel state..will put that back
696 * on-channel at the end of scanning.
697 */
698 ieee80211_offchannel_return(local, false);
699 662
700 *next_delay = HZ / 5; 663 *next_delay = HZ / 5;
701 /* afterwards, resume scan & go to next channel */ 664 /* afterwards, resume scan & go to next channel */
@@ -705,8 +668,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
705static void ieee80211_scan_state_resume(struct ieee80211_local *local, 668static void ieee80211_scan_state_resume(struct ieee80211_local *local,
706 unsigned long *next_delay) 669 unsigned long *next_delay)
707{ 670{
708 /* PS already is in off-channel mode */ 671 ieee80211_offchannel_stop_vifs(local);
709 ieee80211_offchannel_stop_vifs(local, false);
710 672
711 if (local->ops->flush) { 673 if (local->ops->flush) {
712 drv_flush(local, false); 674 drv_flush(local, false);
@@ -832,9 +794,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
832 return res; 794 return res;
833} 795}
834 796
835int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, 797int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
836 const u8 *ssid, u8 ssid_len, 798 const u8 *ssid, u8 ssid_len,
837 struct ieee80211_channel *chan) 799 struct ieee80211_channel *chan)
838{ 800{
839 struct ieee80211_local *local = sdata->local; 801 struct ieee80211_local *local = sdata->local;
840 int ret = -EBUSY; 802 int ret = -EBUSY;
@@ -848,22 +810,36 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
848 810
849 /* fill internal scan request */ 811 /* fill internal scan request */
850 if (!chan) { 812 if (!chan) {
851 int i, nchan = 0; 813 int i, max_n;
814 int n_ch = 0;
852 815
853 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 816 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
854 if (!local->hw.wiphy->bands[band]) 817 if (!local->hw.wiphy->bands[band])
855 continue; 818 continue;
856 for (i = 0; 819
857 i < local->hw.wiphy->bands[band]->n_channels; 820 max_n = local->hw.wiphy->bands[band]->n_channels;
858 i++) { 821 for (i = 0; i < max_n; i++) {
859 local->int_scan_req->channels[nchan] = 822 struct ieee80211_channel *tmp_ch =
860 &local->hw.wiphy->bands[band]->channels[i]; 823 &local->hw.wiphy->bands[band]->channels[i];
861 nchan++; 824
825 if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS |
826 IEEE80211_CHAN_DISABLED))
827 continue;
828
829 local->int_scan_req->channels[n_ch] = tmp_ch;
830 n_ch++;
862 } 831 }
863 } 832 }
864 833
865 local->int_scan_req->n_channels = nchan; 834 if (WARN_ON_ONCE(n_ch == 0))
835 goto unlock;
836
837 local->int_scan_req->n_channels = n_ch;
866 } else { 838 } else {
839 if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS |
840 IEEE80211_CHAN_DISABLED)))
841 goto unlock;
842
867 local->int_scan_req->channels[0] = chan; 843 local->int_scan_req->channels[0] = chan;
868 local->int_scan_req->n_channels = 1; 844 local->int_scan_req->n_channels = 1;
869 } 845 }