summaryrefslogtreecommitdiff
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-09-29 16:04:35 +0200
committerJohn W. Linville <linville@tuxdriver.com>2011-09-30 15:57:18 -0400
commitdeeaee197b0fa694ba6c8f02cdb57b3be7115b4f (patch)
tree9cdd2ce5786ceb60c68327da441913b56de9726c /net/mac80211/sta_info.c
parentce662b44ce22e3e8886104d5feb2a451d7ba560f (diff)
mac80211: reply only once to each PS-poll
If a PS-poll frame is retried (but was received) there is no way to detect that since it has no sequence number. As a consequence, the standard asks us to not react to PS-poll frames until the response to one made it out (was ACKed or lost). Implement this by using the WLAN_STA_SP flags to also indicate a PS-Poll "service period" and the IEEE80211_TX_STATUS_EOSP flag for the response packet to indicate the end of the "SP" as usual. We could use separate flags, but that will most likely completely confuse drivers, and while the standard doesn't exclude simultaneously polling using uAPSD and PS-Poll, doing that seems quite problematic. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d9cb56f548a..5732e4d0cc2 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1217,13 +1217,12 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
/*
* Tell TX path to send this frame even though the
* STA may still remain is PS mode after this frame
- * exchange.
+ * exchange. Also set EOSP to indicate this packet
+ * ends the poll/service period.
*/
- info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE;
-
- if (uapsd)
- info->flags |= IEEE80211_TX_STATUS_EOSP |
- IEEE80211_TX_CTL_REQ_TX_STATUS;
+ info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE |
+ IEEE80211_TX_STATUS_EOSP |
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
ieee80211_xmit(sdata, skb);
}
@@ -1241,6 +1240,9 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
unsigned long driver_release_tids = 0;
struct sk_buff_head frames;
+ /* Service or PS-Poll period starts */
+ set_sta_flags(sta, WLAN_STA_SP);
+
__skb_queue_head_init(&frames);
/*
@@ -1357,10 +1359,11 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
/* set EOSP for the frame */
u8 *p = ieee80211_get_qos_ctl(hdr);
*p |= IEEE80211_QOS_CTL_EOSP;
- info->flags |= IEEE80211_TX_STATUS_EOSP |
- IEEE80211_TX_CTL_REQ_TX_STATUS;
}
+ info->flags |= IEEE80211_TX_STATUS_EOSP |
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
+
__skb_queue_tail(&pending, skb);
}
@@ -1422,9 +1425,6 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)
if (!delivery_enabled)
return;
- /* Ohh, finally, the service period starts :-) */
- set_sta_flags(sta, WLAN_STA_SP);
-
switch (sta->sta.max_sp) {
case 1:
n_frames = 2;