aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h31
-rw-r--r--net/mac80211/driver-ops.h15
-rw-r--r--net/mac80211/driver-trace.h35
-rw-r--r--net/mac80211/sta_info.c82
4 files changed, 147 insertions, 16 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index acf9eaf59641..dc2ea46eb5d6 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1622,6 +1622,14 @@ enum ieee80211_tx_sync_type {
1622}; 1622};
1623 1623
1624/** 1624/**
1625 * enum ieee80211_frame_release_type - frame release reason
1626 * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll
1627 */
1628enum ieee80211_frame_release_type {
1629 IEEE80211_FRAME_RELEASE_PSPOLL,
1630};
1631
1632/**
1625 * struct ieee80211_ops - callbacks from mac80211 to the driver 1633 * struct ieee80211_ops - callbacks from mac80211 to the driver
1626 * 1634 *
1627 * This structure contains various callbacks that the driver may 1635 * This structure contains various callbacks that the driver may
@@ -1931,6 +1939,23 @@ enum ieee80211_tx_sync_type {
1931 * The callback can sleep. 1939 * The callback can sleep.
1932 * @rssi_callback: Notify driver when the average RSSI goes above/below 1940 * @rssi_callback: Notify driver when the average RSSI goes above/below
1933 * thresholds that were registered previously. The callback can sleep. 1941 * thresholds that were registered previously. The callback can sleep.
1942 *
1943 * @release_buffered_frames: Release buffered frames according to the given
1944 * parameters. In the case where the driver buffers some frames for
1945 * sleeping stations mac80211 will use this callback to tell the driver
1946 * to release some frames, either for PS-poll or uAPSD.
1947 * Note that if the @more_data paramter is %false the driver must check
1948 * if there are more frames on the given TIDs, and if there are more than
1949 * the frames being released then it must still set the more-data bit in
1950 * the frame. If the @more_data parameter is %true, then of course the
1951 * more-data bit must always be set.
1952 * The @tids parameter tells the driver which TIDs to release frames
1953 * from, for PS-poll it will always have only a single bit set.
1954 * In the case this is used for uAPSD, the @num_frames parameter may be
1955 * bigger than one, but the driver may send fewer frames (it must send
1956 * at least one, however). In this case it is also responsible for
1957 * setting the EOSP flag in the QoS header of the frames.
1958 * This callback must be atomic.
1934 */ 1959 */
1935struct ieee80211_ops { 1960struct ieee80211_ops {
1936 void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); 1961 void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -2045,6 +2070,12 @@ struct ieee80211_ops {
2045 const struct cfg80211_bitrate_mask *mask); 2070 const struct cfg80211_bitrate_mask *mask);
2046 void (*rssi_callback)(struct ieee80211_hw *hw, 2071 void (*rssi_callback)(struct ieee80211_hw *hw,
2047 enum ieee80211_rssi_event rssi_event); 2072 enum ieee80211_rssi_event rssi_event);
2073
2074 void (*release_buffered_frames)(struct ieee80211_hw *hw,
2075 struct ieee80211_sta *sta,
2076 u16 tids, int num_frames,
2077 enum ieee80211_frame_release_type reason,
2078 bool more_data);
2048}; 2079};
2049 2080
2050/** 2081/**
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 4f845c0845ee..8fa0d2edf54c 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -670,4 +670,19 @@ static inline void drv_rssi_callback(struct ieee80211_local *local,
670 local->ops->rssi_callback(&local->hw, event); 670 local->ops->rssi_callback(&local->hw, event);
671 trace_drv_return_void(local); 671 trace_drv_return_void(local);
672} 672}
673
674static inline void
675drv_release_buffered_frames(struct ieee80211_local *local,
676 struct sta_info *sta, u16 tids, int num_frames,
677 enum ieee80211_frame_release_type reason,
678 bool more_data)
679{
680 trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
681 reason, more_data);
682 if (local->ops->release_buffered_frames)
683 local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
684 num_frames, reason,
685 more_data);
686 trace_drv_return_void(local);
687}
673#endif /* __MAC80211_DRIVER_OPS */ 688#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index a46b279bbbe4..531fbd086794 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -1129,6 +1129,41 @@ TRACE_EVENT(drv_rssi_callback,
1129 ) 1129 )
1130); 1130);
1131 1131
1132TRACE_EVENT(drv_release_buffered_frames,
1133 TP_PROTO(struct ieee80211_local *local,
1134 struct ieee80211_sta *sta,
1135 u16 tids, int num_frames,
1136 enum ieee80211_frame_release_type reason,
1137 bool more_data),
1138
1139 TP_ARGS(local, sta, tids, num_frames, reason, more_data),
1140
1141 TP_STRUCT__entry(
1142 LOCAL_ENTRY
1143 STA_ENTRY
1144 __field(u16, tids)
1145 __field(int, num_frames)
1146 __field(int, reason)
1147 __field(bool, more_data)
1148 ),
1149
1150 TP_fast_assign(
1151 LOCAL_ASSIGN;
1152 STA_ASSIGN;
1153 __entry->tids = tids;
1154 __entry->num_frames = num_frames;
1155 __entry->reason = reason;
1156 __entry->more_data = more_data;
1157 ),
1158
1159 TP_printk(
1160 LOCAL_PR_FMT STA_PR_FMT
1161 " TIDs:0x%.4x frames:%d reason:%d more:%d",
1162 LOCAL_PR_ARG, STA_PR_ARG, __entry->tids, __entry->num_frames,
1163 __entry->reason, __entry->more_data
1164 )
1165);
1166
1132/* 1167/*
1133 * Tracing for API calls that drivers call. 1168 * Tracing for API calls that drivers call.
1134 */ 1169 */
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