From 948d887dec1042a7d78ae311908113e26502062f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 29 Sep 2011 16:04:29 +0200 Subject: mac80211: split PS buffers into ACs For uAPSD support we'll need to have per-AC PS buffers. As this is a major undertaking, split the buffers before really adding support for uAPSD. This already makes some reference to the uapsd_queues variable, but for now that will never be non-zero. Since book-keeping is complicated, also change the logic for keeping a maximum of frames only and allow 64 frames per AC (up from 128 for a station). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/status.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'net/mac80211/status.c') diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 783542a8ea20..c06857bbd573 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -14,6 +14,7 @@ #include "rate.h" #include "mesh.h" #include "led.h" +#include "wme.h" void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, @@ -43,6 +44,8 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + int ac; /* * This skb 'survived' a round-trip through the driver, and @@ -62,6 +65,14 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, sta->tx_filtered_count++; + if (ieee80211_is_data_qos(hdr->frame_control)) { + int tid = *ieee80211_get_qos_ctl(hdr) & + IEEE80211_QOS_CTL_TID_MASK; + ac = ieee802_1d_to_ac[tid & 7]; + } else { + ac = IEEE80211_AC_BE; + } + /* * Clear the TX filter mask for this STA when sending the next * packet. If the STA went to power save mode, this will happen @@ -104,8 +115,8 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, * unknown. */ if (test_sta_flags(sta, WLAN_STA_PS_STA) && - skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { - skb_queue_tail(&sta->tx_filtered, skb); + skb_queue_len(&sta->tx_filtered[ac]) < STA_MAX_TX_BUFFER) { + skb_queue_tail(&sta->tx_filtered[ac], skb); sta_info_recalc_tim(sta); if (!timer_pending(&local->sta_cleanup)) @@ -127,7 +138,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, if (net_ratelimit()) wiphy_debug(local->hw.wiphy, "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", - skb_queue_len(&sta->tx_filtered), + skb_queue_len(&sta->tx_filtered[ac]), !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); #endif dev_kfree_skb(skb); -- cgit v1.2.3