diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-12-18 11:20:48 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-01-05 16:07:12 -0500 |
commit | 90fc4b3a5ba24f09af2a8c4a723651a328949460 (patch) | |
tree | 0ec7031f451f8a7eb38259b6fe80ec52cf780b43 /net/mac80211/offchannel.c | |
parent | 21f83589644bb2ed98079bf1e2154c8e70ca6a6c (diff) |
mac80211: implement off-channel TX using hw r-o-c offload
When the driver has remain-on-channel offload,
implement off-channel transmission using that
primitive.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/offchannel.c')
-rw-r--r-- | net/mac80211/offchannel.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 49b9ec22d9b6..b4e52676f3fb 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -196,6 +196,7 @@ static void ieee80211_hw_roc_start(struct work_struct *work) | |||
196 | { | 196 | { |
197 | struct ieee80211_local *local = | 197 | struct ieee80211_local *local = |
198 | container_of(work, struct ieee80211_local, hw_roc_start); | 198 | container_of(work, struct ieee80211_local, hw_roc_start); |
199 | struct ieee80211_sub_if_data *sdata; | ||
199 | 200 | ||
200 | mutex_lock(&local->mtx); | 201 | mutex_lock(&local->mtx); |
201 | 202 | ||
@@ -206,11 +207,19 @@ static void ieee80211_hw_roc_start(struct work_struct *work) | |||
206 | 207 | ||
207 | ieee80211_recalc_idle(local); | 208 | ieee80211_recalc_idle(local); |
208 | 209 | ||
209 | cfg80211_ready_on_channel(local->hw_roc_dev, local->hw_roc_cookie, | 210 | if (local->hw_roc_skb) { |
210 | local->hw_roc_channel, | 211 | sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev); |
211 | local->hw_roc_channel_type, | 212 | ieee80211_tx_skb(sdata, local->hw_roc_skb); |
212 | local->hw_roc_duration, | 213 | local->hw_roc_skb = NULL; |
213 | GFP_KERNEL); | 214 | } else { |
215 | cfg80211_ready_on_channel(local->hw_roc_dev, | ||
216 | local->hw_roc_cookie, | ||
217 | local->hw_roc_channel, | ||
218 | local->hw_roc_channel_type, | ||
219 | local->hw_roc_duration, | ||
220 | GFP_KERNEL); | ||
221 | } | ||
222 | |||
214 | mutex_unlock(&local->mtx); | 223 | mutex_unlock(&local->mtx); |
215 | } | 224 | } |
216 | 225 | ||
@@ -236,11 +245,12 @@ static void ieee80211_hw_roc_done(struct work_struct *work) | |||
236 | return; | 245 | return; |
237 | } | 246 | } |
238 | 247 | ||
239 | cfg80211_remain_on_channel_expired(local->hw_roc_dev, | 248 | if (!local->hw_roc_for_tx) |
240 | local->hw_roc_cookie, | 249 | cfg80211_remain_on_channel_expired(local->hw_roc_dev, |
241 | local->hw_roc_channel, | 250 | local->hw_roc_cookie, |
242 | local->hw_roc_channel_type, | 251 | local->hw_roc_channel, |
243 | GFP_KERNEL); | 252 | local->hw_roc_channel_type, |
253 | GFP_KERNEL); | ||
244 | 254 | ||
245 | local->hw_roc_channel = NULL; | 255 | local->hw_roc_channel = NULL; |
246 | local->hw_roc_cookie = 0; | 256 | local->hw_roc_cookie = 0; |