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>
This commit is contained in:
Kalle Valo 2010-01-12 10:42:46 +02:00 committed by John W. Linville
parent 50ae0cf15c
commit 5c1b98a52c

View File

@ -180,6 +180,46 @@ static int inline is_ieee80211_device(struct ieee80211_local *local,
}
/* tx handlers */
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
{
struct ieee80211_local *local = tx->local;
/* driver doesn't support power save */
if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
return TX_CONTINUE;
/* hardware does dynamic power save */
if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
return TX_CONTINUE;
/* dynamic power save disabled */
if (local->hw.conf.dynamic_ps_timeout <= 0)
return TX_CONTINUE;
/* we are scanning, don't enable power save */
if (local->scanning)
return TX_CONTINUE;
if (!local->ps_sdata)
return TX_CONTINUE;
/* No point if we're going to suspend */
if (local->quiescing)
return TX_CONTINUE;
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
ieee80211_stop_queues_by_reason(&local->hw,
IEEE80211_QUEUE_STOP_REASON_PS);
ieee80211_queue_work(&local->hw,
&local->dynamic_ps_disable_work);
}
mod_timer(&local->dynamic_ps_timer, jiffies +
msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
return TX_CONTINUE;
}
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
@ -1223,6 +1263,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
goto txh_done; \
} while (0)
CALL_TXH(ieee80211_tx_h_dynamic_ps);
CALL_TXH(ieee80211_tx_h_check_assoc);
CALL_TXH(ieee80211_tx_h_ps_buf);
CALL_TXH(ieee80211_tx_h_select_key);
@ -1405,34 +1446,6 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
return 0;
}
static bool need_dynamic_ps(struct ieee80211_local *local)
{
/* driver doesn't support power save */
if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
return false;
/* hardware does dynamic power save */
if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
return false;
/* dynamic power save disabled */
if (local->hw.conf.dynamic_ps_timeout <= 0)
return false;
/* we are scanning, don't enable power save */
if (local->scanning)
return false;
if (!local->ps_sdata)
return false;
/* No point if we're going to suspend */
if (local->quiescing)
return false;
return true;
}
static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
@ -1443,18 +1456,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
int headroom;
bool may_encrypt;
if (need_dynamic_ps(local)) {
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
ieee80211_stop_queues_by_reason(&local->hw,
IEEE80211_QUEUE_STOP_REASON_PS);
ieee80211_queue_work(&local->hw,
&local->dynamic_ps_disable_work);
}
mod_timer(&local->dynamic_ps_timer, jiffies +
msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
}
rcu_read_lock();
if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {