From 953f6209c00f016d645e4704895d2191f3e77249 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Wed, 6 Apr 2011 11:41:10 +0530 Subject: [PATCH] --- yaml --- r: 246795 b: refs/heads/master c: e8306f989483e4b97a8b37dd268de6c8c6f35e75 h: refs/heads/master i: 246793: d565339ae2107c4f7ab00f35314dc4815c883e26 246791: b42948b813ff366b355809132d4237371859b8b8 v: v3 --- [refs] | 2 +- trunk/include/net/mac80211.h | 4 ++++ trunk/net/mac80211/driver-ops.h | 13 +++++++++++++ trunk/net/mac80211/driver-trace.h | 20 ++++++++++++++++++++ trunk/net/mac80211/mlme.c | 17 +++++++++-------- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index 9fe0d74ecf08..8ed06f2b3065 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6fc3ba999994b675c4e6af77ac4e1a6bfd8e6128 +refs/heads/master: e8306f989483e4b97a8b37dd268de6c8c6f35e75 diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index 965f1b16e53a..361bc5d85b1a 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -1819,6 +1819,9 @@ enum ieee80211_ampdu_mlme_action { * @set_ringparam: Set tx and rx ring sizes. * * @get_ringparam: Get tx and rx ring current and maximum sizes. + * + * @tx_frames_pending: Check if there is any pending frame in the hardware + * queues before entering power save. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); @@ -1906,6 +1909,7 @@ struct ieee80211_ops { int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); void (*get_ringparam)(struct ieee80211_hw *hw, u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); + bool (*tx_frames_pending)(struct ieee80211_hw *hw); }; /** diff --git a/trunk/net/mac80211/driver-ops.h b/trunk/net/mac80211/driver-ops.h index 9c0d62bb0ea3..00a0685f2403 100644 --- a/trunk/net/mac80211/driver-ops.h +++ b/trunk/net/mac80211/driver-ops.h @@ -552,4 +552,17 @@ static inline void drv_get_ringparam(struct ieee80211_local *local, trace_drv_return_void(local); } +static inline bool drv_tx_frames_pending(struct ieee80211_local *local) +{ + bool ret = false; + + might_sleep(); + + trace_drv_tx_frames_pending(local); + if (local->ops->tx_frames_pending) + ret = local->ops->tx_frames_pending(&local->hw); + trace_drv_return_bool(local, ret); + + return ret; +} #endif /* __MAC80211_DRIVER_OPS */ diff --git a/trunk/net/mac80211/driver-trace.h b/trunk/net/mac80211/driver-trace.h index 45aab80738e2..c8c934d48b7a 100644 --- a/trunk/net/mac80211/driver-trace.h +++ b/trunk/net/mac80211/driver-trace.h @@ -74,6 +74,21 @@ TRACE_EVENT(drv_return_int, TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret) ); +TRACE_EVENT(drv_return_bool, + TP_PROTO(struct ieee80211_local *local, bool ret), + TP_ARGS(local, ret), + TP_STRUCT__entry( + LOCAL_ENTRY + __field(bool, ret) + ), + TP_fast_assign( + LOCAL_ASSIGN; + __entry->ret = ret; + ), + TP_printk(LOCAL_PR_FMT " - %s", LOCAL_PR_ARG, (__entry->ret) ? + "true" : "false") +); + TRACE_EVENT(drv_return_u64, TP_PROTO(struct ieee80211_local *local, u64 ret), TP_ARGS(local, ret), @@ -964,6 +979,11 @@ TRACE_EVENT(drv_get_ringparam, ) ); +DEFINE_EVENT(local_only_evt, drv_tx_frames_pending, + TP_PROTO(struct ieee80211_local *local), + TP_ARGS(local) +); + DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, TP_PROTO(struct ieee80211_local *local), TP_ARGS(local) diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 865fed4cc18b..a41f234bd486 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -761,15 +761,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { netif_tx_stop_all_queues(sdata->dev); - /* - * Flush all the frames queued in the driver before - * going to power save - */ - drv_flush(local, false); - ieee80211_send_nullfunc(local, sdata, 1); - /* Flush once again to get the tx status of nullfunc frame */ - drv_flush(local, false); + if (drv_tx_frames_pending(local)) + mod_timer(&local->dynamic_ps_timer, jiffies + + msecs_to_jiffies( + local->hw.conf.dynamic_ps_timeout)); + else { + ieee80211_send_nullfunc(local, sdata, 1); + /* Flush to get the tx status of nullfunc frame */ + drv_flush(local, false); + } } if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&