summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorWei Ni <wni@nvidia.com>2011-11-22 18:17:43 +0800
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-07-12 08:28:05 -0700
commit44713c41b7857936322397eb8f75d14b6e913d4b (patch)
treec46978899295e517f718b62419d2062bde2883d1 /net
parentddb5f0fe7d694255237edd3576d39247907d4f3a (diff)
mac80211 & nl80211: add support to abort a scan request on tx
This fix comes from: https://gerrit.chromium.org/gerrit/#change,5744 https://gerrit.chromium.org/gerrit/#change,5745 So that it can work with the related wpa_supplicant tool. BUG=895591 Change-Id: Ie81f6d6052bd45dab13c936f9f0c5f4eb277496a Original-Signed-off-by: Wei Ni <wni@nvidia.com> Signed-off-by: Rhyland Klein <rklein@nvidia.com> Reviewed-on: http://git-master/r/111333 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/scan.c50
-rw-r--r--net/wireless/nl80211.c7
3 files changed, 53 insertions, 10 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9fab144cc9f5..8624f27441f2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -718,6 +718,10 @@ enum {
* about us leaving the channel and stop all associated STA interfaces
* @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the
* AP about us being back and restart all associated STA interfaces
+ * @SCAN_ABORT: Abnormally terminate the scan operation, set only when
+ * on the operating channel
+ * @SCAN_ENTER_OPER_CHANNEL_ABORT: Return to the operating channel then
+ * terminate the scan operation
*/
enum mac80211_scan_state {
SCAN_DECISION,
@@ -725,6 +729,8 @@ enum mac80211_scan_state {
SCAN_SEND_PROBE,
SCAN_LEAVE_OPER_CHANNEL,
SCAN_ENTER_OPER_CHANNEL,
+ SCAN_ABORT,
+ SCAN_ENTER_OPER_CHANNEL_ABORT,
};
struct ieee80211_local {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 6f09eca01112..4aa2cec04f31 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -477,6 +477,7 @@ 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;
+ enum mac80211_scan_state next_scan_state;
/*
* check if at least one STA interface is associated,
@@ -512,13 +513,21 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
/* We're currently on operating channel. */
if (next_chan == local->oper_channel)
/* We don't need to move off of operating channel. */
- local->next_scan_state = SCAN_SET_CHANNEL;
- else
+ next_scan_state = SCAN_SET_CHANNEL;
+ else {
/*
* We do need to leave operating channel, as next
- * scan is somewhere else.
+ * scan is somewhere else, unless
+ * there is pending traffic and the scan request is
+ * marked to abort when this happens
*/
- local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
+ if (associated && !tx_empty &&
+ (local->scan_req->flags &
+ CFG80211_SCAN_FLAG_TX_ABORT))
+ next_scan_state = SCAN_ABORT;
+ else
+ next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
+ }
} else {
/*
* we're currently scanning a different channel, let's
@@ -547,12 +556,24 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
usecs_to_jiffies(min_beacon_int * 1024) *
local->hw.conf.listen_interval);
- if (associated && ( !tx_empty || bad_latency ||
- listen_int_exceeded))
- local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
+ 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_ENTER_OPER_CHANNEL_ABORT;
+ } else
+ next_scan_state = SCAN_ENTER_OPER_CHANNEL;
+ } else if (associated && (bad_latency || listen_int_exceeded))
+ next_scan_state = SCAN_ENTER_OPER_CHANNEL;
else
- local->next_scan_state = SCAN_SET_CHANNEL;
+ next_scan_state = SCAN_SET_CHANNEL;
}
+ local->next_scan_state = next_scan_state;
*next_delay = 0;
}
@@ -596,8 +617,13 @@ static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *loca
*/
ieee80211_offchannel_return(local, true, false);
- *next_delay = HZ / 5;
- local->next_scan_state = SCAN_DECISION;
+ if (local->next_scan_state == SCAN_ENTER_OPER_CHANNEL) {
+ *next_delay = HZ / 5;
+ local->next_scan_state = SCAN_DECISION;
+ } else {
+ *next_delay = 0;
+ local->next_scan_state = SCAN_ABORT;
+ }
}
static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
@@ -741,11 +767,15 @@ void ieee80211_scan_work(struct work_struct *work)
ieee80211_scan_state_send_probe(local, &next_delay);
break;
case SCAN_LEAVE_OPER_CHANNEL:
+ case SCAN_ENTER_OPER_CHANNEL_ABORT:
ieee80211_scan_state_leave_oper_channel(local, &next_delay);
break;
case SCAN_ENTER_OPER_CHANNEL:
ieee80211_scan_state_enter_oper_channel(local, &next_delay);
break;
+ case SCAN_ABORT:
+ aborted = true;
+ goto out_complete;
}
} while (next_delay == 0);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d7b91a351f84..84400e3a17b6 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -131,6 +131,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
[NL80211_ATTR_IE] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
+ [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
[NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
[NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
@@ -3457,6 +3458,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
request->ie_len);
}
+ if (info->attrs[NL80211_ATTR_SCAN_FLAGS])
+ request->flags = nla_get_u32(
+ info->attrs[NL80211_ATTR_SCAN_FLAGS]);
+
for (i = 0; i < IEEE80211_NUM_BANDS; i++)
if (wiphy->bands[i])
request->rates[i] =
@@ -6158,6 +6163,8 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
if (req->ie)
NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie);
+ NLA_PUT_U8(msg, NL80211_ATTR_SCAN_FLAGS, req->flags);
+
return 0;
nla_put_failure:
return -ENOBUFS;