diff options
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index c70e17677135..9f8412c48960 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -487,6 +487,9 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, unsigned long min_beacon_int = 0; struct ieee80211_sub_if_data *sdata; struct ieee80211_channel *next_chan; +#ifdef CONFIG_MAC80211_SCAN_ABORT + enum mac80211_scan_state next_scan_state; +#endif /* * check if at least one STA interface is associated, @@ -545,10 +548,31 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, usecs_to_jiffies(min_beacon_int * 1024) * local->hw.conf.listen_interval); +#ifndef CONFIG_MAC80211_SCAN_ABORT if (associated && (!tx_empty || bad_latency || listen_int_exceeded)) local->next_scan_state = SCAN_SUSPEND; else local->next_scan_state = SCAN_SET_CHANNEL; +#else + if (associated && !tx_empty) { + if (unlikely(local->scan_req->flags & + CFG80211_SCAN_FLAG_TX_ABORT)) { + /* + * Scan request is marked to abort when there + * is outbound traffic. Mark state to return + * the operating channel and then abort. This + * happens as soon as possible. + */ + next_scan_state = SCAN_SUSPEND_ABORT; + } else + next_scan_state = SCAN_SUSPEND; + } else if (associated && (bad_latency || listen_int_exceeded)) + next_scan_state = SCAN_SUSPEND; + else + next_scan_state = SCAN_SET_CHANNEL; + + local->next_scan_state = next_scan_state; +#endif *next_delay = 0; } @@ -636,9 +660,20 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, */ ieee80211_offchannel_return(local, false); +#ifndef CONFIG_MAC80211_SCAN_ABORT *next_delay = HZ / 5; /* afterwards, resume scan & go to next channel */ local->next_scan_state = SCAN_RESUME; +#else + if (local->next_scan_state == SCAN_SUSPEND) { + *next_delay = HZ / 5; + /* afterwards, resume scan & go to next channel */ + local->next_scan_state = SCAN_RESUME; + } else { + *next_delay = 0; + local->next_scan_state = SCAN_ABORT; + } +#endif } static void ieee80211_scan_state_resume(struct ieee80211_local *local, @@ -731,11 +766,19 @@ void ieee80211_scan_work(struct work_struct *work) ieee80211_scan_state_send_probe(local, &next_delay); break; case SCAN_SUSPEND: +#ifdef CONFIG_MAC80211_SCAN_ABORT + case SCAN_SUSPEND_ABORT: +#endif ieee80211_scan_state_suspend(local, &next_delay); break; case SCAN_RESUME: ieee80211_scan_state_resume(local, &next_delay); break; +#ifdef CONFIG_MAC80211_SCAN_ABORT + case SCAN_ABORT: + aborted = true; + goto out_complete; +#endif } } while (next_delay == 0); |