diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/scan.c | 13 | ||||
-rw-r--r-- | net/mac80211/tx.c | 14 |
2 files changed, 26 insertions, 1 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 5030a3c87509..46f35dc6accb 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -409,6 +409,19 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata, | |||
409 | return 0; | 409 | return 0; |
410 | } | 410 | } |
411 | 411 | ||
412 | /* | ||
413 | * Hardware/driver doesn't support hw_scan, so use software | ||
414 | * scanning instead. First send a nullfunc frame with power save | ||
415 | * bit on so that AP will buffer the frames for us while we are not | ||
416 | * listening, then send probe requests to each channel and wait for | ||
417 | * the responses. After all channels are scanned, tune back to the | ||
418 | * original channel and send a nullfunc frame with power save bit | ||
419 | * off to trigger the AP to send us all the buffered frames. | ||
420 | * | ||
421 | * Note that while local->sw_scanning is true everything else but | ||
422 | * nullfunc frames and probe requests will be dropped in | ||
423 | * ieee80211_tx_h_check_assoc(). | ||
424 | */ | ||
412 | local->sw_scanning = true; | 425 | local->sw_scanning = true; |
413 | if (local->ops->sw_scan_start) | 426 | if (local->ops->sw_scan_start) |
414 | local->ops->sw_scan_start(local_to_hw(local)); | 427 | local->ops->sw_scan_start(local_to_hw(local)); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 038460b0a48a..f3f240c69018 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -193,7 +193,19 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
193 | return TX_CONTINUE; | 193 | return TX_CONTINUE; |
194 | 194 | ||
195 | if (unlikely(tx->local->sw_scanning) && | 195 | if (unlikely(tx->local->sw_scanning) && |
196 | !ieee80211_is_probe_req(hdr->frame_control)) | 196 | !ieee80211_is_probe_req(hdr->frame_control) && |
197 | !ieee80211_is_nullfunc(hdr->frame_control)) | ||
198 | /* | ||
199 | * When software scanning only nullfunc frames (to notify | ||
200 | * the sleep state to the AP) and probe requests (for the | ||
201 | * active scan) are allowed, all other frames should not be | ||
202 | * sent and we should not get here, but if we do | ||
203 | * nonetheless, drop them to avoid sending them | ||
204 | * off-channel. See the link below and | ||
205 | * ieee80211_start_scan() for more. | ||
206 | * | ||
207 | * http://article.gmane.org/gmane.linux.kernel.wireless.general/30089 | ||
208 | */ | ||
197 | return TX_DROP; | 209 | return TX_DROP; |
198 | 210 | ||
199 | if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | 211 | if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) |