aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/tx.c81
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 */
183static ieee80211_tx_result debug_noinline
184ieee80211_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
184static ieee80211_tx_result debug_noinline 224static ieee80211_tx_result debug_noinline
185ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) 225ieee80211_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
1408static 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
1436static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, 1449static 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)) {