aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c82
1 files changed, 66 insertions, 16 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 4d85672f0b8f..b3f841948c09 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1157,8 +1157,10 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1157 struct ieee80211_sub_if_data *sdata = sta->sdata; 1157 struct ieee80211_sub_if_data *sdata = sta->sdata;
1158 struct ieee80211_local *local = sdata->local; 1158 struct ieee80211_local *local = sdata->local;
1159 struct sk_buff *skb = NULL; 1159 struct sk_buff *skb = NULL;
1160 bool found = false;
1160 bool more_data = false; 1161 bool more_data = false;
1161 int ac; 1162 int ac;
1163 unsigned long driver_release_tids = 0;
1162 u8 ignore_for_response = sta->sta.uapsd_queues; 1164 u8 ignore_for_response = sta->sta.uapsd_queues;
1163 1165
1164 /* 1166 /*
@@ -1173,19 +1175,40 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1173 * Get response frame and more data bit for it. 1175 * Get response frame and more data bit for it.
1174 */ 1176 */
1175 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 1177 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
1178 unsigned long tids;
1179
1176 if (ignore_for_response & BIT(ac)) 1180 if (ignore_for_response & BIT(ac))
1177 continue; 1181 continue;
1178 1182
1179 if (!skb) { 1183 tids = ieee80211_tids_for_ac(ac);
1180 skb = skb_dequeue(&sta->tx_filtered[ac]); 1184
1181 if (!skb) { 1185 if (!found) {
1182 skb = skb_dequeue(&sta->ps_tx_buf[ac]); 1186 driver_release_tids = sta->driver_buffered_tids & tids;
1187 if (driver_release_tids) {
1188 found = true;
1189 } else {
1190 skb = skb_dequeue(&sta->tx_filtered[ac]);
1191 if (!skb) {
1192 skb = skb_dequeue(&sta->ps_tx_buf[ac]);
1193 if (skb)
1194 local->total_ps_buffered--;
1195 }
1183 if (skb) 1196 if (skb)
1184 local->total_ps_buffered--; 1197 found = true;
1185 } 1198 }
1186 }
1187 1199
1188 /* FIXME: take into account driver-buffered frames */ 1200 /*
1201 * If the driver has data on more than one TID then
1202 * certainly there's more data if we release just a
1203 * single frame now (from a single TID).
1204 */
1205 if (hweight16(driver_release_tids) > 1) {
1206 more_data = true;
1207 driver_release_tids =
1208 BIT(ffs(driver_release_tids) - 1);
1209 break;
1210 }
1211 }
1189 1212
1190 if (!skb_queue_empty(&sta->tx_filtered[ac]) || 1213 if (!skb_queue_empty(&sta->tx_filtered[ac]) ||
1191 !skb_queue_empty(&sta->ps_tx_buf[ac])) { 1214 !skb_queue_empty(&sta->ps_tx_buf[ac])) {
@@ -1194,6 +1217,22 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1194 } 1217 }
1195 } 1218 }
1196 1219
1220 if (!found) {
1221#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1222 /*
1223 * FIXME: This can be the result of a race condition between
1224 * us expiring a frame and the station polling for it.
1225 * Should we send it a null-func frame indicating we
1226 * have nothing buffered for it?
1227 */
1228 printk(KERN_DEBUG "%s: STA %pM sent PS Poll even "
1229 "though there are no buffered frames for it\n",
1230 sdata->name, sta->sta.addr);
1231#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1232
1233 return;
1234 }
1235
1197 if (skb) { 1236 if (skb) {
1198 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1237 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1199 struct ieee80211_hdr *hdr = 1238 struct ieee80211_hdr *hdr =
@@ -1220,18 +1259,29 @@ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta)
1220 ieee80211_add_pending_skb(local, skb); 1259 ieee80211_add_pending_skb(local, skb);
1221 1260
1222 sta_info_recalc_tim(sta); 1261 sta_info_recalc_tim(sta);
1223#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1224 } else { 1262 } else {
1225 /* 1263 /*
1226 * FIXME: This can be the result of a race condition between 1264 * We need to release a frame that is buffered somewhere in the
1227 * us expiring a frame and the station polling for it. 1265 * driver ... it'll have to handle that.
1228 * Should we send it a null-func frame indicating we 1266 * Note that, as per the comment above, it'll also have to see
1229 * have nothing buffered for it? 1267 * if there is more than just one frame on the specific TID that
1268 * we're releasing from, and it needs to set the more-data bit
1269 * accordingly if we tell it that there's no more data. If we do
1270 * tell it there's more data, then of course the more-data bit
1271 * needs to be set anyway.
1272 */
1273 drv_release_buffered_frames(local, sta, driver_release_tids,
1274 1, IEEE80211_FRAME_RELEASE_PSPOLL,
1275 more_data);
1276
1277 /*
1278 * Note that we don't recalculate the TIM bit here as it would
1279 * most likely have no effect at all unless the driver told us
1280 * that the TID became empty before returning here from the
1281 * release function.
1282 * Either way, however, when the driver tells us that the TID
1283 * became empty we'll do the TIM recalculation.
1230 */ 1284 */
1231 printk(KERN_DEBUG "%s: STA %pM sent PS Poll even "
1232 "though there are no buffered frames for it\n",
1233 sdata->name, sta->sta.addr);
1234#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1235 } 1285 }
1236} 1286}
1237 1287