summaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
authorSeth Forshee <seth.forshee@canonical.com>2013-02-11 11:21:07 -0600
committerJohannes Berg <johannes.berg@intel.com>2013-02-11 22:52:21 +0100
commit6c17b77b67587b9f9e3070fb89fe98cef3187131 (patch)
tree5e47a8feb14ec822b276c893a9fb3cca93e6bbd0 /net/mac80211/scan.c
parentdf15a6c4fa7f77511663d7b5f9134f37ad2e8c92 (diff)
downloadlinux-stable-6c17b77b67587b9f9e3070fb89fe98cef3187131.tar.gz
linux-stable-6c17b77b67587b9f9e3070fb89fe98cef3187131.tar.bz2
linux-stable-6c17b77b67587b9f9e3070fb89fe98cef3187131.zip
mac80211: Fix tx queue handling during scans
Scans currently work by stopping the netdev tx queues but leaving the mac80211 queues active. This stops the flow of incoming packets while still allowing mac80211 to transmit nullfunc and probe request frames to facilitate scanning. However, the driver may try to wake the mac80211 queues while in this state, which will also wake the netdev queues. To prevent this, add a new queue stop reason, IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, to be used when stopping the tx queues for off-channel operation. This prevents the netdev queues from waking when a driver wakes the mac80211 queues. This also stops all frames from being transmitted, even those meant to be sent off-channel. Add a new tx control flag, IEEE80211_TX_CTL_OFFCHAN_TX_OK, which allows frames to be transmitted when the queues are stopped only for the off-channel stop reason. Update all locations transmitting off-channel frames to use this flag. Signed-off-by: Seth Forshee <seth.forshee@canonical.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index edd47d9acb99..d9e2df96f676 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -382,6 +382,11 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
int i;
struct ieee80211_sub_if_data *sdata;
enum ieee80211_band band = local->hw.conf.channel->band;
+ u32 tx_flags;
+
+ tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
+ if (local->scan_req->no_cck)
+ tx_flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
sdata = rcu_dereference_protected(local->scan_sdata,
lockdep_is_held(&local->mtx));
@@ -393,9 +398,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
local->scan_req->ssids[i].ssid_len,
local->scan_req->ie, local->scan_req->ie_len,
local->scan_req->rates[band], false,
- local->scan_req->no_cck ?
- IEEE80211_TX_CTL_NO_CCK_RATE : 0,
- local->hw.conf.channel, true);
+ tx_flags, local->hw.conf.channel, true);
/*
* After sending probe requests, wait for probe responses