aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-09-29 10:04:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-30 15:57:15 -0400
commit47086fc51aa2220f58049704a8b73e4fcdf372b9 (patch)
tree31f7ae0e59318352d772b62fa26316d349cde88e /net/mac80211
parent4049e09acdf4ffd270cb8fbf1cf5b39c3d02357c (diff)
mac80211: implement uAPSD
Add uAPSD support to mac80211. This is probably not possible with all devices, so advertising it with the cfg80211 flag will be left up to drivers that want it. Due to my previous patches it is now a fairly straight-forward extension. Drivers need to have accurate TX status reporting for the EOSP frame. For drivers that buffer themselves, the provided APIs allow releasing the right number of frames, but then drivers need to set EOSP and more-data themselves. This is documented in more detail in the new code itself. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/rx.c102
-rw-r--r--net/mac80211/sta_info.c170
-rw-r--r--net/mac80211/sta_info.h8
-rw-r--r--net/mac80211/status.c15
-rw-r--r--net/mac80211/tx.c8
5 files changed, 224 insertions, 79 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index db46601e50bf..9a703f00b5fb 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1163,6 +1163,79 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)
1163EXPORT_SYMBOL(ieee80211_sta_ps_transition); 1163EXPORT_SYMBOL(ieee80211_sta_ps_transition);
1164 1164
1165static ieee80211_rx_result debug_noinline 1165static ieee80211_rx_result debug_noinline
1166ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
1167{
1168 struct ieee80211_sub_if_data *sdata = rx->sdata;
1169 struct ieee80211_hdr *hdr = (void *)rx->skb->data;
1170 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1171 int tid, ac;
1172
1173 if (!rx->sta || !(status->rx_flags & IEEE80211_RX_RA_MATCH))
1174 return RX_CONTINUE;
1175
1176 if (sdata->vif.type != NL80211_IFTYPE_AP &&
1177 sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
1178 return RX_CONTINUE;
1179
1180 /*
1181 * The device handles station powersave, so don't do anything about
1182 * uAPSD and PS-Poll frames (the latter shouldn't even come up from
1183 * it to mac80211 since they're handled.)
1184 */
1185 if (sdata->local->hw.flags & IEEE80211_HW_AP_LINK_PS)
1186 return RX_CONTINUE;
1187
1188 /*
1189 * Don't do anything if the station isn't already asleep. In
1190 * the uAPSD case, the station will probably be marked asleep,
1191 * in the PS-Poll case the station must be confused ...
1192 */
1193 if (!test_sta_flags(rx->sta, WLAN_STA_PS_STA))
1194 return RX_CONTINUE;
1195
1196 if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) {
1197 if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
1198 ieee80211_sta_ps_deliver_poll_response(rx->sta);
1199 else
1200 set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
1201
1202 /* Free PS Poll skb here instead of returning RX_DROP that would
1203 * count as an dropped frame. */
1204 dev_kfree_skb(rx->skb);
1205
1206 return RX_QUEUED;
1207 } else if (!ieee80211_has_morefrags(hdr->frame_control) &&
1208 !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
1209 ieee80211_has_pm(hdr->frame_control) &&
1210 (ieee80211_is_data_qos(hdr->frame_control) ||
1211 ieee80211_is_qos_nullfunc(hdr->frame_control))) {
1212 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
1213 ac = ieee802_1d_to_ac[tid & 7];
1214
1215 /*
1216 * If this AC is not trigger-enabled do nothing.
1217 *
1218 * NB: This could/should check a separate bitmap of trigger-
1219 * enabled queues, but for now we only implement uAPSD w/o
1220 * TSPEC changes to the ACs, so they're always the same.
1221 */
1222 if (!(rx->sta->sta.uapsd_queues & BIT(ac)))
1223 return RX_CONTINUE;
1224
1225 /* if we are in a service period, do nothing */
1226 if (test_sta_flags(rx->sta, WLAN_STA_SP))
1227 return RX_CONTINUE;
1228
1229 if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
1230 ieee80211_sta_ps_deliver_uapsd(rx->sta);
1231 else
1232 set_sta_flags(rx->sta, WLAN_STA_UAPSD);
1233 }
1234
1235 return RX_CONTINUE;
1236}
1237
1238static ieee80211_rx_result debug_noinline
1166ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) 1239ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1167{ 1240{
1168 struct sta_info *sta = rx->sta; 1241 struct sta_info *sta = rx->sta;
@@ -1473,33 +1546,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1473} 1546}
1474 1547
1475static ieee80211_rx_result debug_noinline 1548static ieee80211_rx_result debug_noinline
1476ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1477{
1478 struct ieee80211_sub_if_data *sdata = rx->sdata;
1479 __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
1480 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1481
1482 if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
1483 !(status->rx_flags & IEEE80211_RX_RA_MATCH)))
1484 return RX_CONTINUE;
1485
1486 if ((sdata->vif.type != NL80211_IFTYPE_AP) &&
1487 (sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
1488 return RX_DROP_UNUSABLE;
1489
1490 if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
1491 ieee80211_sta_ps_deliver_poll_response(rx->sta);
1492 else
1493 set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
1494
1495 /* Free PS Poll skb here instead of returning RX_DROP that would
1496 * count as an dropped frame. */
1497 dev_kfree_skb(rx->skb);
1498
1499 return RX_QUEUED;
1500}
1501
1502static ieee80211_rx_result debug_noinline
1503ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) 1549ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
1504{ 1550{
1505 u8 *data = rx->skb->data; 1551 u8 *data = rx->skb->data;
@@ -2567,9 +2613,9 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
2567 2613
2568 CALL_RXH(ieee80211_rx_h_decrypt) 2614 CALL_RXH(ieee80211_rx_h_decrypt)
2569 CALL_RXH(ieee80211_rx_h_check_more_data) 2615 CALL_RXH(ieee80211_rx_h_check_more_data)
2616 CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll)
2570 CALL_RXH(ieee80211_rx_h_sta_process) 2617 CALL_RXH(ieee80211_rx_h_sta_process)
2571 CALL_RXH(ieee80211_rx_h_defragment) 2618 CALL_RXH(ieee80211_rx_h_defragment)
2572 CALL_RXH(ieee80211_rx_h_ps_poll)
2573 CALL_RXH(ieee80211_rx_h_michael_mic_verify) 2619 CALL_RXH(ieee80211_rx_h_michael_mic_verify)
2574 /* must be after MMIC verify so header is counted in MPDU mic */ 2620 /* must be after MMIC verify so header is counted in MPDU mic */
2575#ifdef CONFIG_MAC80211_MESH 2621#ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index b3f841948c09..f9079e478f77 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -248,6 +248,9 @@ static void sta_unblock(struct work_struct *wk)
248 else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) { 248 else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
249 clear_sta_flags(sta, WLAN_STA_PS_DRIVER); 249 clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
250 ieee80211_sta_ps_deliver_poll_response(sta); 250 ieee80211_sta_ps_deliver_poll_response(sta);
251 } else if (test_and_clear_sta_flags(sta, WLAN_STA_UAPSD)) {
252 clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
253 ieee80211_sta_ps_deliver_uapsd(sta);
251 } else 254 } else
252 clear_sta_flags(sta, WLAN_STA_PS_DRIVER); 255 clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
253} 256}
@@ -1117,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
1117 struct sk_buff_head pending; 1120 struct sk_buff_head pending;
1118 int filtered = 0, buffered = 0, ac; 1121 int filtered = 0, buffered = 0, ac;
1119 1122
1123 clear_sta_flags(sta, WLAN_STA_SP);
1124
1120 BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1); 1125 BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1);
1121 sta->driver_buffered_tids = 0; 1126 sta->driver_buffered_tids = 0;
1122 1127
@@ -1152,32 +1157,28 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
1152#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 1157#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1153} 1158}
1154 1159
1155void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta) 1160static void
1161ieee80211_sta_ps_deliver_response(struct sta_info *sta,
1162 int n_frames, u8 ignored_acs,
1163 enum ieee80211_frame_release_type reason)
1156{ 1164{
1157 struct ieee80211_sub_if_data *sdata = sta->sdata; 1165 struct ieee80211_sub_if_data *sdata = sta->sdata;
1158 struct ieee80211_local *local = sdata->local; 1166 struct ieee80211_local *local = sdata->local;
1159 struct sk_buff *skb = NULL;
1160 bool found = false; 1167 bool found = false;
1161 bool more_data = false; 1168 bool more_data = false;
1162 int ac; 1169 int ac;
1163 unsigned long driver_release_tids = 0; 1170 unsigned long driver_release_tids = 0;
1164 u8 ignore_for_response = sta->sta.uapsd_queues; 1171 struct sk_buff_head frames;
1165 1172
1166 /* 1173 __skb_queue_head_init(&frames);
1167 * If all ACs are delivery-enabled then we should reply
1168 * from any of them, if only some are enabled we reply
1169 * only from the non-enabled ones.
1170 */
1171 if (ignore_for_response == BIT(IEEE80211_NUM_ACS) - 1)
1172 ignore_for_response = 0;
1173 1174
1174 /* 1175 /*
1175 * Get response frame and more data bit for it. 1176 * Get response frame(s) and more data bit for it.
1176 */ 1177 */
1177 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 1178 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
1178 unsigned long tids; 1179 unsigned long tids;
1179 1180
1180 if (ignore_for_response & BIT(ac)) 1181 if (ignored_acs & BIT(ac))
1181 continue; 1182 continue;
1182 1183
1183 tids = ieee80211_tids_for_ac(ac); 1184 tids = ieee80211_tids_for_ac(ac);
@@ -1187,14 +1188,22 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1187 if (driver_release_tids) { 1188 if (driver_release_tids) {
1188 found = true; 1189 found = true;
1189 } else { 1190 } else {
1190 skb = skb_dequeue(&sta->tx_filtered[ac]); 1191 struct sk_buff *skb;
1191 if (!skb) { 1192
1192 skb = skb_dequeue(&sta->ps_tx_buf[ac]); 1193 while (n_frames > 0) {
1193 if (skb) 1194 skb = skb_dequeue(&sta->tx_filtered[ac]);
1194 local->total_ps_buffered--; 1195 if (!skb) {
1195 } 1196 skb = skb_dequeue(
1196 if (skb) 1197 &sta->ps_tx_buf[ac]);
1198 if (skb)
1199 local->total_ps_buffered--;
1200 }
1201 if (!skb)
1202 break;
1203 n_frames--;
1197 found = true; 1204 found = true;
1205 __skb_queue_tail(&frames, skb);
1206 }
1198 } 1207 }
1199 1208
1200 /* 1209 /*
@@ -1202,7 +1211,8 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1202 * certainly there's more data if we release just a 1211 * certainly there's more data if we release just a
1203 * single frame now (from a single TID). 1212 * single frame now (from a single TID).
1204 */ 1213 */
1205 if (hweight16(driver_release_tids) > 1) { 1214 if (reason == IEEE80211_FRAME_RELEASE_PSPOLL &&
1215 hweight16(driver_release_tids) > 1) {
1206 more_data = true; 1216 more_data = true;
1207 driver_release_tids = 1217 driver_release_tids =
1208 BIT(ffs(driver_release_tids) - 1); 1218 BIT(ffs(driver_release_tids) - 1);
@@ -1225,38 +1235,56 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1225 * Should we send it a null-func frame indicating we 1235 * Should we send it a null-func frame indicating we
1226 * have nothing buffered for it? 1236 * have nothing buffered for it?
1227 */ 1237 */
1228 printk(KERN_DEBUG "%s: STA %pM sent PS Poll even " 1238 if (reason == IEEE80211_FRAME_RELEASE_PSPOLL)
1229 "though there are no buffered frames for it\n", 1239 printk(KERN_DEBUG "%s: STA %pM sent PS Poll even "
1230 sdata->name, sta->sta.addr); 1240 "though there are no buffered frames for it\n",
1241 sdata->name, sta->sta.addr);
1231#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 1242#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1232 1243
1233 return; 1244 return;
1234 } 1245 }
1235 1246
1236 if (skb) { 1247 if (!driver_release_tids) {
1237 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1248 struct sk_buff_head pending;
1238 struct ieee80211_hdr *hdr = 1249 struct sk_buff *skb;
1239 (struct ieee80211_hdr *) skb->data;
1240 1250
1241 /* 1251 skb_queue_head_init(&pending);
1242 * Tell TX path to send this frame even though the STA may
1243 * still remain is PS mode after this frame exchange.
1244 */
1245 info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE;
1246 1252
1247#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1253 while ((skb = __skb_dequeue(&frames))) {
1248 printk(KERN_DEBUG "STA %pM aid %d: PS Poll\n", 1254 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1249 sta->sta.addr, sta->sta.aid); 1255 struct ieee80211_hdr *hdr = (void *) skb->data;
1250#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1251 1256
1252 /* Use MoreData flag to indicate whether there are more 1257 /*
1253 * buffered frames for this STA */ 1258 * Tell TX path to send this frame even though the
1254 if (!more_data) 1259 * STA may still remain is PS mode after this frame
1255 hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA); 1260 * exchange.
1256 else 1261 */
1257 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1262 info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE;
1263
1264 /*
1265 * Use MoreData flag to indicate whether there are
1266 * more buffered frames for this STA
1267 */
1268 if (!more_data)
1269 hdr->frame_control &=
1270 cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
1271 else
1272 hdr->frame_control |=
1273 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1274
1275 if (reason == IEEE80211_FRAME_RELEASE_UAPSD &&
1276 skb_queue_empty(&frames)) {
1277 /* set EOSP for the frame */
1278 u8 *p = ieee80211_get_qos_ctl(hdr);
1279 *p |= IEEE80211_QOS_CTL_EOSP;
1280 info->flags |= IEEE80211_TX_STATUS_EOSP |
1281 IEEE80211_TX_CTL_REQ_TX_STATUS;
1282 }
1258 1283
1259 ieee80211_add_pending_skb(local, skb); 1284 __skb_queue_tail(&pending, skb);
1285 }
1286
1287 ieee80211_add_pending_skbs(local, &pending);
1260 1288
1261 sta_info_recalc_tim(sta); 1289 sta_info_recalc_tim(sta);
1262 } else { 1290 } else {
@@ -1271,8 +1299,7 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1271 * needs to be set anyway. 1299 * needs to be set anyway.
1272 */ 1300 */
1273 drv_release_buffered_frames(local, sta, driver_release_tids, 1301 drv_release_buffered_frames(local, sta, driver_release_tids,
1274 1, IEEE80211_FRAME_RELEASE_PSPOLL, 1302 n_frames, reason, more_data);
1275 more_data);
1276 1303
1277 /* 1304 /*
1278 * Note that we don't recalculate the TIM bit here as it would 1305 * Note that we don't recalculate the TIM bit here as it would
@@ -1285,6 +1312,59 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1285 } 1312 }
1286} 1313}
1287 1314
1315void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1316{
1317 u8 ignore_for_response = sta->sta.uapsd_queues;
1318
1319 /*
1320 * If all ACs are delivery-enabled then we should reply
1321 * from any of them, if only some are enabled we reply
1322 * only from the non-enabled ones.
1323 */
1324 if (ignore_for_response == BIT(IEEE80211_NUM_ACS) - 1)
1325 ignore_for_response = 0;
1326
1327 ieee80211_sta_ps_deliver_response(sta, 1, ignore_for_response,
1328 IEEE80211_FRAME_RELEASE_PSPOLL);
1329}
1330
1331void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)
1332{
1333 int n_frames = sta->sta.max_sp;
1334 u8 delivery_enabled = sta->sta.uapsd_queues;
1335
1336 /*
1337 * If we ever grow support for TSPEC this might happen if
1338 * the TSPEC update from hostapd comes in between a trigger
1339 * frame setting WLAN_STA_UAPSD in the RX path and this
1340 * actually getting called.
1341 */
1342 if (!delivery_enabled)
1343 return;
1344
1345 /* Ohh, finally, the service period starts :-) */
1346 set_sta_flags(sta, WLAN_STA_SP);
1347
1348 switch (sta->sta.max_sp) {
1349 case 1:
1350 n_frames = 2;
1351 break;
1352 case 2:
1353 n_frames = 4;
1354 break;
1355 case 3:
1356 n_frames = 6;
1357 break;
1358 case 0:
1359 /* XXX: what is a good value? */
1360 n_frames = 8;
1361 break;
1362 }
1363
1364 ieee80211_sta_ps_deliver_response(sta, n_frames, ~delivery_enabled,
1365 IEEE80211_FRAME_RELEASE_UAPSD);
1366}
1367
1288void ieee80211_sta_block_awake(struct ieee80211_hw *hw, 1368void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
1289 struct ieee80211_sta *pubsta, bool block) 1369 struct ieee80211_sta *pubsta, bool block)
1290{ 1370{
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 8589afad3295..751ad25f925f 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -46,6 +46,11 @@
46 * @WLAN_STA_TDLS_PEER: Station is a TDLS peer. 46 * @WLAN_STA_TDLS_PEER: Station is a TDLS peer.
47 * @WLAN_STA_TDLS_PEER_AUTH: This TDLS peer is authorized to send direct 47 * @WLAN_STA_TDLS_PEER_AUTH: This TDLS peer is authorized to send direct
48 * packets. This means the link is enabled. 48 * packets. This means the link is enabled.
49 * @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was
50 * keeping station in power-save mode, reply when the driver
51 * unblocks the station.
52 * @WLAN_STA_SP: Station is in a service period, so don't try to
53 * reply to other uAPSD trigger frames.
49 */ 54 */
50enum ieee80211_sta_info_flags { 55enum ieee80211_sta_info_flags {
51 WLAN_STA_AUTH = 1<<0, 56 WLAN_STA_AUTH = 1<<0,
@@ -63,6 +68,8 @@ enum ieee80211_sta_info_flags {
63 WLAN_STA_PSPOLL = 1<<13, 68 WLAN_STA_PSPOLL = 1<<13,
64 WLAN_STA_TDLS_PEER = 1<<15, 69 WLAN_STA_TDLS_PEER = 1<<15,
65 WLAN_STA_TDLS_PEER_AUTH = 1<<16, 70 WLAN_STA_TDLS_PEER_AUTH = 1<<16,
71 WLAN_STA_UAPSD = 1<<17,
72 WLAN_STA_SP = 1<<18,
66}; 73};
67 74
68#define STA_TID_NUM 16 75#define STA_TID_NUM 16
@@ -539,5 +546,6 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
539 546
540void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); 547void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
541void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); 548void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
549void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta);
542 550
543#endif /* STA_INFO_H */ 551#endif /* STA_INFO_H */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 94475eb51d28..b5df9be4d043 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -76,8 +76,16 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
76 hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA); 76 hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
77 77
78 if (ieee80211_is_data_qos(hdr->frame_control)) { 78 if (ieee80211_is_data_qos(hdr->frame_control)) {
79 int tid = *ieee80211_get_qos_ctl(hdr) & 79 u8 *p = ieee80211_get_qos_ctl(hdr);
80 IEEE80211_QOS_CTL_TID_MASK; 80 int tid = *p & IEEE80211_QOS_CTL_TID_MASK;
81
82 /*
83 * Clear EOSP if set, this could happen e.g.
84 * if an absence period (us being a P2P GO)
85 * shortens the SP.
86 */
87 if (*p & IEEE80211_QOS_CTL_EOSP)
88 *p &= ~IEEE80211_QOS_CTL_EOSP;
81 ac = ieee802_1d_to_ac[tid & 7]; 89 ac = ieee802_1d_to_ac[tid & 7];
82 } else { 90 } else {
83 ac = IEEE80211_AC_BE; 91 ac = IEEE80211_AC_BE;
@@ -276,6 +284,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
276 if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) 284 if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
277 continue; 285 continue;
278 286
287 if (info->flags & IEEE80211_TX_STATUS_EOSP)
288 clear_sta_flags(sta, WLAN_STA_SP);
289
279 acked = !!(info->flags & IEEE80211_TX_STAT_ACK); 290 acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
280 if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) { 291 if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) {
281 /* 292 /*
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index a1029449df44..a0676d39fe8f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -456,7 +456,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
456 staflags = get_sta_flags(sta); 456 staflags = get_sta_flags(sta);
457 457
458 if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) && 458 if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) &&
459 !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { 459 !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) {
460 int ac = skb_get_queue_mapping(tx->skb); 460 int ac = skb_get_queue_mapping(tx->skb);
461 461
462#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 462#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
@@ -497,9 +497,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
497 } 497 }
498#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 498#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
499 else if (unlikely(staflags & WLAN_STA_PS_STA)) { 499 else if (unlikely(staflags & WLAN_STA_PS_STA)) {
500 printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " 500 printk(KERN_DEBUG
501 "set -> send frame\n", tx->sdata->name, 501 "%s: STA %pM in PS mode, but polling/in SP -> send frame\n",
502 sta->sta.addr); 502 tx->sdata->name, sta->sta.addr);
503 } 503 }
504#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 504#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
505 505