diff options
author | Kalle Valo <kalle.valo@nokia.com> | 2010-01-12 03:42:46 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-12 14:21:01 -0500 |
commit | 5c1b98a52c3af1044c2d3842af8bae9a89502ca9 (patch) | |
tree | 6df9e13ba8fb0213238e56be04361efa3c1af139 /net/mac80211/tx.c | |
parent | 50ae0cf15c3da2f6a8e4558de5010923e84736b2 (diff) |
mac80211: create tx handler for dynamic ps
Currently dynamic ps check is in ieee80211_xmit(), but it's cleaner
to have a separate tx handler for this. Also this is a prerequisite for
U-APSD client mode which needs to know the queue frame is in.
Also need_dynamic_ps() function is embedded to the tx handler.
No functional changes expect that the code is run in a later phase than
originally.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 81 |
1 files changed, 41 insertions, 40 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 47ca59e52e71..6fcc85a2806a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -180,6 +180,46 @@ static int inline is_ieee80211_device(struct ieee80211_local *local, | |||
180 | } | 180 | } |
181 | 181 | ||
182 | /* tx handlers */ | 182 | /* tx handlers */ |
183 | static ieee80211_tx_result debug_noinline | ||
184 | ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) | ||
185 | { | ||
186 | struct ieee80211_local *local = tx->local; | ||
187 | |||
188 | /* driver doesn't support power save */ | ||
189 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) | ||
190 | return TX_CONTINUE; | ||
191 | |||
192 | /* hardware does dynamic power save */ | ||
193 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) | ||
194 | return TX_CONTINUE; | ||
195 | |||
196 | /* dynamic power save disabled */ | ||
197 | if (local->hw.conf.dynamic_ps_timeout <= 0) | ||
198 | return TX_CONTINUE; | ||
199 | |||
200 | /* we are scanning, don't enable power save */ | ||
201 | if (local->scanning) | ||
202 | return TX_CONTINUE; | ||
203 | |||
204 | if (!local->ps_sdata) | ||
205 | return TX_CONTINUE; | ||
206 | |||
207 | /* No point if we're going to suspend */ | ||
208 | if (local->quiescing) | ||
209 | return TX_CONTINUE; | ||
210 | |||
211 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
212 | ieee80211_stop_queues_by_reason(&local->hw, | ||
213 | IEEE80211_QUEUE_STOP_REASON_PS); | ||
214 | ieee80211_queue_work(&local->hw, | ||
215 | &local->dynamic_ps_disable_work); | ||
216 | } | ||
217 | |||
218 | mod_timer(&local->dynamic_ps_timer, jiffies + | ||
219 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | ||
220 | |||
221 | return TX_CONTINUE; | ||
222 | } | ||
183 | 223 | ||
184 | static ieee80211_tx_result debug_noinline | 224 | static ieee80211_tx_result debug_noinline |
185 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | 225 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) |
@@ -1223,6 +1263,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1223 | goto txh_done; \ | 1263 | goto txh_done; \ |
1224 | } while (0) | 1264 | } while (0) |
1225 | 1265 | ||
1266 | CALL_TXH(ieee80211_tx_h_dynamic_ps); | ||
1226 | CALL_TXH(ieee80211_tx_h_check_assoc); | 1267 | CALL_TXH(ieee80211_tx_h_check_assoc); |
1227 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1268 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1228 | CALL_TXH(ieee80211_tx_h_select_key); | 1269 | CALL_TXH(ieee80211_tx_h_select_key); |
@@ -1405,34 +1446,6 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
1405 | return 0; | 1446 | return 0; |
1406 | } | 1447 | } |
1407 | 1448 | ||
1408 | static bool need_dynamic_ps(struct ieee80211_local *local) | ||
1409 | { | ||
1410 | /* driver doesn't support power save */ | ||
1411 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) | ||
1412 | return false; | ||
1413 | |||
1414 | /* hardware does dynamic power save */ | ||
1415 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) | ||
1416 | return false; | ||
1417 | |||
1418 | /* dynamic power save disabled */ | ||
1419 | if (local->hw.conf.dynamic_ps_timeout <= 0) | ||
1420 | return false; | ||
1421 | |||
1422 | /* we are scanning, don't enable power save */ | ||
1423 | if (local->scanning) | ||
1424 | return false; | ||
1425 | |||
1426 | if (!local->ps_sdata) | ||
1427 | return false; | ||
1428 | |||
1429 | /* No point if we're going to suspend */ | ||
1430 | if (local->quiescing) | ||
1431 | return false; | ||
1432 | |||
1433 | return true; | ||
1434 | } | ||
1435 | |||
1436 | static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | 1449 | static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, |
1437 | struct sk_buff *skb) | 1450 | struct sk_buff *skb) |
1438 | { | 1451 | { |
@@ -1443,18 +1456,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1443 | int headroom; | 1456 | int headroom; |
1444 | bool may_encrypt; | 1457 | bool may_encrypt; |
1445 | 1458 | ||
1446 | if (need_dynamic_ps(local)) { | ||
1447 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
1448 | ieee80211_stop_queues_by_reason(&local->hw, | ||
1449 | IEEE80211_QUEUE_STOP_REASON_PS); | ||
1450 | ieee80211_queue_work(&local->hw, | ||
1451 | &local->dynamic_ps_disable_work); | ||
1452 | } | ||
1453 | |||
1454 | mod_timer(&local->dynamic_ps_timer, jiffies + | ||
1455 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | ||
1456 | } | ||
1457 | |||
1458 | rcu_read_lock(); | 1459 | rcu_read_lock(); |
1459 | 1460 | ||
1460 | if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { | 1461 | if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { |