summaryrefslogtreecommitdiff
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c43
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);