aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/status.c')
-rw-r--r--net/mac80211/status.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 56d5b9a6ec5b..94613af009f3 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -171,13 +171,16 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
171 struct net_device *prev_dev = NULL; 171 struct net_device *prev_dev = NULL;
172 struct sta_info *sta, *tmp; 172 struct sta_info *sta, *tmp;
173 int retry_count = -1, i; 173 int retry_count = -1, i;
174 bool injected; 174 int rates_idx = -1;
175 bool send_to_cooked;
175 176
176 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 177 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
177 /* the HW cannot have attempted that rate */ 178 /* the HW cannot have attempted that rate */
178 if (i >= hw->max_rates) { 179 if (i >= hw->max_rates) {
179 info->status.rates[i].idx = -1; 180 info->status.rates[i].idx = -1;
180 info->status.rates[i].count = 0; 181 info->status.rates[i].count = 0;
182 } else if (info->status.rates[i].idx >= 0) {
183 rates_idx = i;
181 } 184 }
182 185
183 retry_count += info->status.rates[i].count; 186 retry_count += info->status.rates[i].count;
@@ -206,6 +209,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
206 return; 209 return;
207 } 210 }
208 211
212 if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
213 (rates_idx != -1))
214 sta->last_tx_rate = info->status.rates[rates_idx];
215
209 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && 216 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
210 (ieee80211_is_data_qos(fc))) { 217 (ieee80211_is_data_qos(fc))) {
211 u16 tid, ssn; 218 u16 tid, ssn;
@@ -296,11 +303,15 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
296 /* this was a transmitted frame, but now we want to reuse it */ 303 /* this was a transmitted frame, but now we want to reuse it */
297 skb_orphan(skb); 304 skb_orphan(skb);
298 305
306 /* Need to make a copy before skb->cb gets cleared */
307 send_to_cooked = !!(info->flags & IEEE80211_TX_CTL_INJECTED) ||
308 (type != IEEE80211_FTYPE_DATA);
309
299 /* 310 /*
300 * This is a bit racy but we can avoid a lot of work 311 * This is a bit racy but we can avoid a lot of work
301 * with this test... 312 * with this test...
302 */ 313 */
303 if (!local->monitors && !local->cooked_mntrs) { 314 if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
304 dev_kfree_skb(skb); 315 dev_kfree_skb(skb);
305 return; 316 return;
306 } 317 }
@@ -345,9 +356,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
345 /* for now report the total retry_count */ 356 /* for now report the total retry_count */
346 rthdr->data_retries = retry_count; 357 rthdr->data_retries = retry_count;
347 358
348 /* Need to make a copy before skb->cb gets cleared */
349 injected = !!(info->flags & IEEE80211_TX_CTL_INJECTED);
350
351 /* XXX: is this sufficient for BPF? */ 359 /* XXX: is this sufficient for BPF? */
352 skb_set_mac_header(skb, 0); 360 skb_set_mac_header(skb, 0);
353 skb->ip_summed = CHECKSUM_UNNECESSARY; 361 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -362,8 +370,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
362 continue; 370 continue;
363 371
364 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) && 372 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
365 !injected && 373 !send_to_cooked)
366 (type == IEEE80211_FTYPE_DATA))
367 continue; 374 continue;
368 375
369 if (prev_dev) { 376 if (prev_dev) {