Blame view

net/mac80211/status.c 19.5 KB
fe7a5d5c1   Johannes Berg   mac80211: move TX...
1
2
3
4
  /*
   * Copyright 2002-2005, Instant802 Networks, Inc.
   * Copyright 2005-2006, Devicescape Software, Inc.
   * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
026331c4d   Jouni Malinen   cfg80211/mac80211...
5
   * Copyright 2008-2010	Johannes Berg <johannes@sipsolutions.net>
fe7a5d5c1   Johannes Berg   mac80211: move TX...
6
7
8
9
10
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
bc3b2d7fb   Paul Gortmaker   net: Add export.h...
11
  #include <linux/export.h>
fe7a5d5c1   Johannes Berg   mac80211: move TX...
12
13
14
15
16
  #include <net/mac80211.h>
  #include "ieee80211_i.h"
  #include "rate.h"
  #include "mesh.h"
  #include "led.h"
948d887de   Johannes Berg   mac80211: split P...
17
  #include "wme.h"
fe7a5d5c1   Johannes Berg   mac80211: move TX...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  
  
  void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
  				 struct sk_buff *skb)
  {
  	struct ieee80211_local *local = hw_to_local(hw);
  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  	int tmp;
  
  	skb->pkt_type = IEEE80211_TX_STATUS_MSG;
  	skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ?
  		       &local->skb_queue : &local->skb_queue_unreliable, skb);
  	tmp = skb_queue_len(&local->skb_queue) +
  		skb_queue_len(&local->skb_queue_unreliable);
  	while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT &&
  	       (skb = skb_dequeue(&local->skb_queue_unreliable))) {
  		dev_kfree_skb_irq(skb);
  		tmp--;
  		I802_DEBUG_INC(local->tx_status_drop);
  	}
  	tasklet_schedule(&local->tasklet);
  }
  EXPORT_SYMBOL(ieee80211_tx_status_irqsafe);
  
  static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
  					    struct sta_info *sta,
  					    struct sk_buff *skb)
  {
  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
948d887de   Johannes Berg   mac80211: split P...
47
48
  	struct ieee80211_hdr *hdr = (void *)skb->data;
  	int ac;
fe7a5d5c1   Johannes Berg   mac80211: move TX...
49
50
  
  	/*
697e6a0fb   Johannes Berg   mac80211: clear T...
51
52
  	 * This skb 'survived' a round-trip through the driver, and
  	 * hopefully the driver didn't mangle it too badly. However,
77c2061d1   Walter Goldens   wireless: fix sev...
53
  	 * we can definitely not rely on the control information
c6fcf6bcf   Johannes Berg   mac80211: re-enab...
54
55
56
  	 * being correct. Clear it so we don't get junk there, and
  	 * indicate that it needs new processing, but must not be
  	 * modified/encrypted again.
697e6a0fb   Johannes Berg   mac80211: clear T...
57
58
  	 */
  	memset(&info->control, 0, sizeof(info->control));
18c949070   Johannes Berg   mac80211: fill ji...
59
60
61
  
  	info->control.jiffies = jiffies;
  	info->control.vif = &sta->sdata->vif;
c6fcf6bcf   Johannes Berg   mac80211: re-enab...
62
63
  	info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING |
  		       IEEE80211_TX_INTFL_RETRANSMISSION;
eb7d3066c   Christian Lamparter   mac80211: clear t...
64
  	info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
697e6a0fb   Johannes Berg   mac80211: clear T...
65

fe7a5d5c1   Johannes Berg   mac80211: move TX...
66
  	sta->tx_filtered_count++;
8a8656fa5   Johannes Berg   mac80211: clear m...
67
68
69
70
71
72
73
74
75
  	/*
  	 * Clear more-data bit on filtered frames, it might be set
  	 * but later frames might time out so it might have to be
  	 * clear again ... It's all rather unlikely (this frame
  	 * should time out first, right?) but let's not confuse
  	 * peers unnecessarily.
  	 */
  	if (hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_MOREDATA))
  		hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
948d887de   Johannes Berg   mac80211: split P...
76
  	if (ieee80211_is_data_qos(hdr->frame_control)) {
47086fc51   Johannes Berg   mac80211: impleme...
77
78
79
80
81
82
83
84
85
86
  		u8 *p = ieee80211_get_qos_ctl(hdr);
  		int tid = *p & IEEE80211_QOS_CTL_TID_MASK;
  
  		/*
  		 * Clear EOSP if set, this could happen e.g.
  		 * if an absence period (us being a P2P GO)
  		 * shortens the SP.
  		 */
  		if (*p & IEEE80211_QOS_CTL_EOSP)
  			*p &= ~IEEE80211_QOS_CTL_EOSP;
948d887de   Johannes Berg   mac80211: split P...
87
88
89
90
  		ac = ieee802_1d_to_ac[tid & 7];
  	} else {
  		ac = IEEE80211_AC_BE;
  	}
fe7a5d5c1   Johannes Berg   mac80211: move TX...
91
92
93
94
95
  	/*
  	 * Clear the TX filter mask for this STA when sending the next
  	 * packet. If the STA went to power save mode, this will happen
  	 * when it wakes up for the next time.
  	 */
c2c98fdeb   Johannes Berg   mac80211: optimis...
96
  	set_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT);
fe7a5d5c1   Johannes Berg   mac80211: move TX...
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  
  	/*
  	 * This code races in the following way:
  	 *
  	 *  (1) STA sends frame indicating it will go to sleep and does so
  	 *  (2) hardware/firmware adds STA to filter list, passes frame up
  	 *  (3) hardware/firmware processes TX fifo and suppresses a frame
  	 *  (4) we get TX status before having processed the frame and
  	 *	knowing that the STA has gone to sleep.
  	 *
  	 * This is actually quite unlikely even when both those events are
  	 * processed from interrupts coming in quickly after one another or
  	 * even at the same time because we queue both TX status events and
  	 * RX frames to be processed by a tasklet and process them in the
  	 * same order that they were received or TX status last. Hence, there
  	 * is no race as long as the frame RX is processed before the next TX
  	 * status, which drivers can ensure, see below.
  	 *
  	 * Note that this can only happen if the hardware or firmware can
  	 * actually add STAs to the filter list, if this is done by the
  	 * driver in response to set_tim() (which will only reduce the race
  	 * this whole filtering tries to solve, not completely solve it)
  	 * this situation cannot happen.
  	 *
  	 * To completely solve this race drivers need to make sure that they
  	 *  (a) don't mix the irq-safe/not irq-safe TX status/RX processing
  	 *	functions and
  	 *  (b) always process RX events before TX status events if ordering
  	 *      can be unknown, for example with different interrupt status
  	 *	bits.
d057e5a38   Arik Nemtsov   mac80211: add HW ...
127
128
129
130
  	 *  (c) if PS mode transitions are manual (i.e. the flag
  	 *      %IEEE80211_HW_AP_LINK_PS is set), always process PS state
  	 *      changes before calling TX status events if ordering can be
  	 *	unknown.
fe7a5d5c1   Johannes Berg   mac80211: move TX...
131
  	 */
c2c98fdeb   Johannes Berg   mac80211: optimis...
132
  	if (test_sta_flag(sta, WLAN_STA_PS_STA) &&
948d887de   Johannes Berg   mac80211: split P...
133
134
  	    skb_queue_len(&sta->tx_filtered[ac]) < STA_MAX_TX_BUFFER) {
  		skb_queue_tail(&sta->tx_filtered[ac], skb);
c868cb35d   Johannes Berg   mac80211: unify T...
135
  		sta_info_recalc_tim(sta);
607503971   Johannes Berg   mac80211: also ex...
136
137
138
139
140
  
  		if (!timer_pending(&local->sta_cleanup))
  			mod_timer(&local->sta_cleanup,
  				  round_jiffies(jiffies +
  						STA_INFO_CLEANUP_INTERVAL));
fe7a5d5c1   Johannes Berg   mac80211: move TX...
141
142
  		return;
  	}
c2c98fdeb   Johannes Berg   mac80211: optimis...
143
  	if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
fe7a5d5c1   Johannes Berg   mac80211: move TX...
144
145
146
147
148
149
  	    !(info->flags & IEEE80211_TX_INTFL_RETRIED)) {
  		/* Software retry the packet once */
  		info->flags |= IEEE80211_TX_INTFL_RETRIED;
  		ieee80211_add_pending_skb(local, skb);
  		return;
  	}
fe7a5d5c1   Johannes Berg   mac80211: move TX...
150
151
  #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
  	if (net_ratelimit())
0fb9a9ec2   Joe Perches   net/mac80211: Use...
152
153
154
  		wiphy_debug(local->hw.wiphy,
  			    "dropped TX filtered frame, queue_len=%d PS=%d @%lu
  ",
948d887de   Johannes Berg   mac80211: split P...
155
  			    skb_queue_len(&sta->tx_filtered[ac]),
c2c98fdeb   Johannes Berg   mac80211: optimis...
156
  			    !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies);
fe7a5d5c1   Johannes Berg   mac80211: move TX...
157
158
159
  #endif
  	dev_kfree_skb(skb);
  }
f0425beda   Felix Fietkau   mac80211: retry s...
160
161
162
163
164
165
166
167
168
  static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid)
  {
  	struct tid_ampdu_tx *tid_tx;
  
  	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
  	if (!tid_tx || !tid_tx->bar_pending)
  		return;
  
  	tid_tx->bar_pending = false;
8c771244f   Felix Fietkau   mac80211: make ie...
169
  	ieee80211_send_bar(&sta->sdata->vif, addr, tid, tid_tx->failed_bar_ssn);
f0425beda   Felix Fietkau   mac80211: retry s...
170
  }
0f78231bf   Johannes Berg   mac80211: enable ...
171
172
173
174
175
  static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
  {
  	struct ieee80211_mgmt *mgmt = (void *) skb->data;
  	struct ieee80211_local *local = sta->local;
  	struct ieee80211_sub_if_data *sdata = sta->sdata;
f0425beda   Felix Fietkau   mac80211: retry s...
176
177
178
179
180
181
182
  	if (ieee80211_is_data_qos(mgmt->frame_control)) {
  		struct ieee80211_hdr *hdr = (void *) skb->data;
  		u8 *qc = ieee80211_get_qos_ctl(hdr);
  		u16 tid = qc[0] & 0xf;
  
  		ieee80211_check_pending_bar(sta, hdr->addr1, tid);
  	}
0f78231bf   Johannes Berg   mac80211: enable ...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  	if (ieee80211_is_action(mgmt->frame_control) &&
  	    sdata->vif.type == NL80211_IFTYPE_STATION &&
  	    mgmt->u.action.category == WLAN_CATEGORY_HT &&
  	    mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS) {
  		/*
  		 * This update looks racy, but isn't -- if we come
  		 * here we've definitely got a station that we're
  		 * talking to, and on a managed interface that can
  		 * only be the AP. And the only other place updating
  		 * this variable is before we're associated.
  		 */
  		switch (mgmt->u.action.u.ht_smps.smps_control) {
  		case WLAN_HT_SMPS_CONTROL_DYNAMIC:
  			sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_DYNAMIC;
  			break;
  		case WLAN_HT_SMPS_CONTROL_STATIC:
  			sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_STATIC;
  			break;
  		case WLAN_HT_SMPS_CONTROL_DISABLED:
  		default: /* shouldn't happen since we don't send that */
  			sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_OFF;
  			break;
  		}
  
  		ieee80211_queue_work(&local->hw, &local->recalc_smps);
  	}
  }
f0425beda   Felix Fietkau   mac80211: retry s...
210
211
212
213
214
215
216
217
218
219
220
  static void ieee80211_set_bar_pending(struct sta_info *sta, u8 tid, u16 ssn)
  {
  	struct tid_ampdu_tx *tid_tx;
  
  	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
  	if (!tid_tx)
  		return;
  
  	tid_tx->failed_bar_ssn = ssn;
  	tid_tx->bar_pending = true;
  }
a2fe81667   Helmut Schaa   mac80211: Build T...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
  static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
  {
  	int len = sizeof(struct ieee80211_radiotap_header);
  
  	/* IEEE80211_RADIOTAP_RATE rate */
  	if (info->status.rates[0].idx >= 0 &&
  	    !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS))
  		len += 2;
  
  	/* IEEE80211_RADIOTAP_TX_FLAGS */
  	len += 2;
  
  	/* IEEE80211_RADIOTAP_DATA_RETRIES */
  	len += 1;
7f2a5e214   Helmut Schaa   mac80211: Populat...
235
236
237
238
  	/* IEEE80211_TX_RC_MCS */
  	if (info->status.rates[0].idx >= 0 &&
  	    info->status.rates[0].flags & IEEE80211_TX_RC_MCS)
  		len += 3;
a2fe81667   Helmut Schaa   mac80211: Build T...
239
240
241
242
243
244
245
246
247
248
249
  	return len;
  }
  
  static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
  					     *sband, struct sk_buff *skb,
  					     int retry_count, int rtap_len)
  {
  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
  	struct ieee80211_radiotap_header *rthdr;
  	unsigned char *pos;
9c8f2c42c   Helmut Schaa   mac80211: Fix end...
250
  	u16 txflags;
a2fe81667   Helmut Schaa   mac80211: Build T...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
  
  	rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len);
  
  	memset(rthdr, 0, rtap_len);
  	rthdr->it_len = cpu_to_le16(rtap_len);
  	rthdr->it_present =
  		cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
  			    (1 << IEEE80211_RADIOTAP_DATA_RETRIES));
  	pos = (unsigned char *)(rthdr + 1);
  
  	/*
  	 * XXX: Once radiotap gets the bitmap reset thing the vendor
  	 *	extensions proposal contains, we can actually report
  	 *	the whole set of tries we did.
  	 */
  
  	/* IEEE80211_RADIOTAP_RATE */
  	if (info->status.rates[0].idx >= 0 &&
  	    !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) {
  		rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
  		*pos = sband->bitrates[info->status.rates[0].idx].bitrate / 5;
  		/* padding for tx flags */
  		pos += 2;
  	}
  
  	/* IEEE80211_RADIOTAP_TX_FLAGS */
  	txflags = 0;
  	if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
  	    !is_multicast_ether_addr(hdr->addr1))
9c8f2c42c   Helmut Schaa   mac80211: Fix end...
280
  		txflags |= IEEE80211_RADIOTAP_F_TX_FAIL;
a2fe81667   Helmut Schaa   mac80211: Build T...
281
282
283
  
  	if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
  	    (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
9c8f2c42c   Helmut Schaa   mac80211: Fix end...
284
  		txflags |= IEEE80211_RADIOTAP_F_TX_CTS;
a2fe81667   Helmut Schaa   mac80211: Build T...
285
  	else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
9c8f2c42c   Helmut Schaa   mac80211: Fix end...
286
  		txflags |= IEEE80211_RADIOTAP_F_TX_RTS;
a2fe81667   Helmut Schaa   mac80211: Build T...
287
288
289
290
291
292
293
294
  
  	put_unaligned_le16(txflags, pos);
  	pos += 2;
  
  	/* IEEE80211_RADIOTAP_DATA_RETRIES */
  	/* for now report the total retry_count */
  	*pos = retry_count;
  	pos++;
7f2a5e214   Helmut Schaa   mac80211: Populat...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
  
  	/* IEEE80211_TX_RC_MCS */
  	if (info->status.rates[0].idx >= 0 &&
  	    info->status.rates[0].flags & IEEE80211_TX_RC_MCS) {
  		rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS);
  		pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
  			 IEEE80211_RADIOTAP_MCS_HAVE_GI |
  			 IEEE80211_RADIOTAP_MCS_HAVE_BW;
  		if (info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
  			pos[1] |= IEEE80211_RADIOTAP_MCS_SGI;
  		if (info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
  			pos[1] |= IEEE80211_RADIOTAP_MCS_BW_40;
  		if (info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)
  			pos[1] |= IEEE80211_RADIOTAP_MCS_FMT_GF;
  		pos[2] = info->status.rates[0].idx;
  		pos += 3;
  	}
a2fe81667   Helmut Schaa   mac80211: Build T...
312
  }
99ba2a142   Johannes Berg   mac80211: impleme...
313
314
315
316
317
318
319
320
  /*
   * Use a static threshold for now, best value to be determined
   * by testing ...
   * Should it depend on:
   *  - on # of retransmissions
   *  - current throughput (higher value for higher tpt)?
   */
  #define STA_LOST_PKT_THRESHOLD	50
fe7a5d5c1   Johannes Berg   mac80211: move TX...
321
322
323
324
325
326
  void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
  {
  	struct sk_buff *skb2;
  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
  	struct ieee80211_local *local = hw_to_local(hw);
  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
fe7a5d5c1   Johannes Berg   mac80211: move TX...
327
328
  	__le16 fc;
  	struct ieee80211_supported_band *sband;
fe7a5d5c1   Johannes Berg   mac80211: move TX...
329
330
  	struct ieee80211_sub_if_data *sdata;
  	struct net_device *prev_dev = NULL;
abe60632f   Johannes Berg   mac80211: make st...
331
  	struct sta_info *sta, *tmp;
fe7a5d5c1   Johannes Berg   mac80211: move TX...
332
  	int retry_count = -1, i;
0c8698081   Juuso Oikarinen   mac80211: Fix sta...
333
  	int rates_idx = -1;
eaf55530c   Felix Fietkau   mac80211: optimiz...
334
  	bool send_to_cooked;
04ac3c0ee   Felix Fietkau   mac80211: speed u...
335
  	bool acked;
e69deded2   Helmut Schaa   mac80211: Tear do...
336
337
  	struct ieee80211_bar *bar;
  	u16 tid;
a2fe81667   Helmut Schaa   mac80211: Build T...
338
  	int rtap_len;
fe7a5d5c1   Johannes Berg   mac80211: move TX...
339
340
  
  	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
be7974aa1   Helmut Schaa   mac80211: Minor o...
341
342
343
344
  		if (info->status.rates[i].idx < 0) {
  			break;
  		} else if (i >= hw->max_report_rates) {
  			/* the HW cannot have attempted that rate */
fe7a5d5c1   Johannes Berg   mac80211: move TX...
345
346
  			info->status.rates[i].idx = -1;
  			info->status.rates[i].count = 0;
be7974aa1   Helmut Schaa   mac80211: Minor o...
347
  			break;
fe7a5d5c1   Johannes Berg   mac80211: move TX...
348
349
350
351
  		}
  
  		retry_count += info->status.rates[i].count;
  	}
be7974aa1   Helmut Schaa   mac80211: Minor o...
352
  	rates_idx = i - 1;
fe7a5d5c1   Johannes Berg   mac80211: move TX...
353
354
355
356
357
358
  	if (retry_count < 0)
  		retry_count = 0;
  
  	rcu_read_lock();
  
  	sband = local->hw.wiphy->bands[info->band];
375177bf3   Vivek Natarajan   mac80211: Retry n...
359
  	fc = hdr->frame_control;
fe7a5d5c1   Johannes Berg   mac80211: move TX...
360

abe60632f   Johannes Berg   mac80211: make st...
361
362
  	for_each_sta_info(local, hdr->addr1, sta, tmp) {
  		/* skip wrong virtual interface */
47846c9b0   Johannes Berg   mac80211: reduce ...
363
  		if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
abe60632f   Johannes Berg   mac80211: make st...
364
  			continue;
fe7a5d5c1   Johannes Berg   mac80211: move TX...
365

47086fc51   Johannes Berg   mac80211: impleme...
366
  		if (info->flags & IEEE80211_TX_STATUS_EOSP)
c2c98fdeb   Johannes Berg   mac80211: optimis...
367
  			clear_sta_flag(sta, WLAN_STA_SP);
47086fc51   Johannes Berg   mac80211: impleme...
368

04ac3c0ee   Felix Fietkau   mac80211: speed u...
369
  		acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
c2c98fdeb   Johannes Berg   mac80211: optimis...
370
  		if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) {
fe7a5d5c1   Johannes Berg   mac80211: move TX...
371
372
373
374
375
376
377
378
  			/*
  			 * The STA is in power save mode, so assume
  			 * that this TX packet failed because of that.
  			 */
  			ieee80211_handle_filtered_frame(local, sta, skb);
  			rcu_read_unlock();
  			return;
  		}
0c8698081   Juuso Oikarinen   mac80211: Fix sta...
379
380
381
  		if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
  		    (rates_idx != -1))
  			sta->last_tx_rate = info->status.rates[rates_idx];
fe7a5d5c1   Johannes Berg   mac80211: move TX...
382
383
384
385
386
387
388
389
390
  		if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
  		    (ieee80211_is_data_qos(fc))) {
  			u16 tid, ssn;
  			u8 *qc;
  
  			qc = ieee80211_get_qos_ctl(hdr);
  			tid = qc[0] & 0xf;
  			ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10)
  						& IEEE80211_SCTL_SEQ);
8c771244f   Felix Fietkau   mac80211: make ie...
391
  			ieee80211_send_bar(&sta->sdata->vif, hdr->addr1,
fe7a5d5c1   Johannes Berg   mac80211: move TX...
392
393
  					   tid, ssn);
  		}
e69deded2   Helmut Schaa   mac80211: Tear do...
394
  		if (!acked && ieee80211_is_back_req(fc)) {
7107676a3   Felix Fietkau   mac80211: fix end...
395
  			u16 control;
e69deded2   Helmut Schaa   mac80211: Tear do...
396
  			/*
7107676a3   Felix Fietkau   mac80211: fix end...
397
398
399
  			 * BAR failed, store the last SSN and retry sending
  			 * the BAR when the next unicast transmission on the
  			 * same TID succeeds.
e69deded2   Helmut Schaa   mac80211: Tear do...
400
401
  			 */
  			bar = (struct ieee80211_bar *) skb->data;
7107676a3   Felix Fietkau   mac80211: fix end...
402
403
  			control = le16_to_cpu(bar->control);
  			if (!(control & IEEE80211_BAR_CTRL_MULTI_TID)) {
f0425beda   Felix Fietkau   mac80211: retry s...
404
  				u16 ssn = le16_to_cpu(bar->start_seq_num);
7107676a3   Felix Fietkau   mac80211: fix end...
405
  				tid = (control &
e69deded2   Helmut Schaa   mac80211: Tear do...
406
407
  				       IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
  				      IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
f0425beda   Felix Fietkau   mac80211: retry s...
408
409
  
  				ieee80211_set_bar_pending(sta, tid, ssn);
e69deded2   Helmut Schaa   mac80211: Tear do...
410
411
  			}
  		}
fe7a5d5c1   Johannes Berg   mac80211: move TX...
412
413
414
415
416
  		if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
  			ieee80211_handle_filtered_frame(local, sta, skb);
  			rcu_read_unlock();
  			return;
  		} else {
04ac3c0ee   Felix Fietkau   mac80211: speed u...
417
  			if (!acked)
fe7a5d5c1   Johannes Berg   mac80211: move TX...
418
419
420
421
422
423
424
  				sta->tx_retry_failed++;
  			sta->tx_retry_count += retry_count;
  		}
  
  		rate_control_tx_status(local, sband, sta, skb);
  		if (ieee80211_vif_is_mesh(&sta->sdata->vif))
  			ieee80211s_update_metric(local, sta, skb);
0f78231bf   Johannes Berg   mac80211: enable ...
425

04ac3c0ee   Felix Fietkau   mac80211: speed u...
426
  		if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked)
0f78231bf   Johannes Berg   mac80211: enable ...
427
  			ieee80211_frame_acked(sta, skb);
99ba2a142   Johannes Berg   mac80211: impleme...
428

04ac3c0ee   Felix Fietkau   mac80211: speed u...
429
430
431
  		if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) &&
  		    (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
  			ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked);
99ba2a142   Johannes Berg   mac80211: impleme...
432
433
434
435
436
437
438
439
440
441
442
443
  		if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
  			if (info->flags & IEEE80211_TX_STAT_ACK) {
  				if (sta->lost_packets)
  					sta->lost_packets = 0;
  			} else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) {
  				cfg80211_cqm_pktloss_notify(sta->sdata->dev,
  							    sta->sta.addr,
  							    sta->lost_packets,
  							    GFP_ATOMIC);
  				sta->lost_packets = 0;
  			}
  		}
fe7a5d5c1   Johannes Berg   mac80211: move TX...
444
445
446
447
448
449
450
451
452
453
  	}
  
  	rcu_read_unlock();
  
  	ieee80211_led_tx(local, 0);
  
  	/* SNMP counters
  	 * Fragments are passed to low-level drivers as separate skbs, so these
  	 * are actually fragments, not frames. Update frame counters only for
  	 * the first fragment of the frame. */
fe7a5d5c1   Johannes Berg   mac80211: move TX...
454
  	if (info->flags & IEEE80211_TX_STAT_ACK) {
adf5ace5d   Helmut Schaa   mac80211: Make us...
455
  		if (ieee80211_is_first_frag(hdr->seq_ctrl)) {
fe7a5d5c1   Johannes Berg   mac80211: move TX...
456
457
458
459
460
461
462
463
464
465
466
467
468
469
  			local->dot11TransmittedFrameCount++;
  			if (is_multicast_ether_addr(hdr->addr1))
  				local->dot11MulticastTransmittedFrameCount++;
  			if (retry_count > 0)
  				local->dot11RetryCount++;
  			if (retry_count > 1)
  				local->dot11MultipleRetryCount++;
  		}
  
  		/* This counter shall be incremented for an acknowledged MPDU
  		 * with an individual address in the address 1 field or an MPDU
  		 * with a multicast address in the address 1 field of type Data
  		 * or Management. */
  		if (!is_multicast_ether_addr(hdr->addr1) ||
adf5ace5d   Helmut Schaa   mac80211: Make us...
470
471
  		    ieee80211_is_data(fc) ||
  		    ieee80211_is_mgmt(fc))
fe7a5d5c1   Johannes Berg   mac80211: move TX...
472
473
  			local->dot11TransmittedFragmentCount++;
  	} else {
adf5ace5d   Helmut Schaa   mac80211: Make us...
474
  		if (ieee80211_is_first_frag(hdr->seq_ctrl))
fe7a5d5c1   Johannes Berg   mac80211: move TX...
475
476
  			local->dot11FailedCount++;
  	}
375177bf3   Vivek Natarajan   mac80211: Retry n...
477
478
479
480
481
482
483
  	if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc) &&
  	    (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
  	    !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
  	    local->ps_sdata && !(local->scanning)) {
  		if (info->flags & IEEE80211_TX_STAT_ACK) {
  			local->ps_sdata->u.mgd.flags |=
  					IEEE80211_STA_NULLFUNC_ACKED;
375177bf3   Vivek Natarajan   mac80211: Retry n...
484
485
486
487
  		} else
  			mod_timer(&local->dynamic_ps_timer, jiffies +
  					msecs_to_jiffies(10));
  	}
f30221e4e   Johannes Berg   mac80211: impleme...
488
  	if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
4334ec851   Johannes Berg   mac80211: fix TX ...
489
  		u64 cookie = (unsigned long)skb;
f30221e4e   Johannes Berg   mac80211: impleme...
490

06500736c   Johannes Berg   mac80211: support...
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
  		if (ieee80211_is_nullfunc(hdr->frame_control) ||
  		    ieee80211_is_qos_nullfunc(hdr->frame_control)) {
  			bool acked = info->flags & IEEE80211_TX_STAT_ACK;
  			cfg80211_probe_status(skb->dev, hdr->addr1,
  					      cookie, acked, GFP_ATOMIC);
  		} else {
  			struct ieee80211_work *wk;
  
  			rcu_read_lock();
  			list_for_each_entry_rcu(wk, &local->work_list, list) {
  				if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
  					continue;
  				if (wk->offchan_tx.frame != skb)
  					continue;
  				wk->offchan_tx.status = true;
  				break;
  			}
  			rcu_read_unlock();
  			if (local->hw_roc_skb_for_status == skb) {
  				cookie = local->hw_roc_cookie ^ 2;
  				local->hw_roc_skb_for_status = NULL;
  			}
5f16a4361   Johannes Berg   mac80211: support...
513

06500736c   Johannes Berg   mac80211: support...
514
515
516
517
518
  			cfg80211_mgmt_tx_status(
  				skb->dev, cookie, skb->data, skb->len,
  				!!(info->flags & IEEE80211_TX_STAT_ACK),
  				GFP_ATOMIC);
  		}
f30221e4e   Johannes Berg   mac80211: impleme...
519
  	}
026331c4d   Jouni Malinen   cfg80211/mac80211...
520

a729cff8a   Johannes Berg   mac80211: impleme...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
  	if (unlikely(info->ack_frame_id)) {
  		struct sk_buff *ack_skb;
  		unsigned long flags;
  
  		spin_lock_irqsave(&local->ack_status_lock, flags);
  		ack_skb = idr_find(&local->ack_status_frames,
  				   info->ack_frame_id);
  		if (ack_skb)
  			idr_remove(&local->ack_status_frames,
  				   info->ack_frame_id);
  		spin_unlock_irqrestore(&local->ack_status_lock, flags);
  
  		/* consumes ack_skb */
  		if (ack_skb)
  			skb_complete_wifi_ack(ack_skb,
  				info->flags & IEEE80211_TX_STAT_ACK);
  	}
fe7a5d5c1   Johannes Berg   mac80211: move TX...
538
539
  	/* this was a transmitted frame, but now we want to reuse it */
  	skb_orphan(skb);
eaf55530c   Felix Fietkau   mac80211: optimiz...
540
541
  	/* Need to make a copy before skb->cb gets cleared */
  	send_to_cooked = !!(info->flags & IEEE80211_TX_CTL_INJECTED) ||
adf5ace5d   Helmut Schaa   mac80211: Make us...
542
  			 !(ieee80211_is_data(fc));
eaf55530c   Felix Fietkau   mac80211: optimiz...
543

fe7a5d5c1   Johannes Berg   mac80211: move TX...
544
545
546
547
  	/*
  	 * This is a bit racy but we can avoid a lot of work
  	 * with this test...
  	 */
eaf55530c   Felix Fietkau   mac80211: optimiz...
548
  	if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
fe7a5d5c1   Johannes Berg   mac80211: move TX...
549
550
551
552
553
  		dev_kfree_skb(skb);
  		return;
  	}
  
  	/* send frame to monitor interfaces now */
a2fe81667   Helmut Schaa   mac80211: Build T...
554
555
  	rtap_len = ieee80211_tx_radiotap_len(info);
  	if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
fe7a5d5c1   Johannes Berg   mac80211: move TX...
556
557
558
559
560
  		printk(KERN_ERR "ieee80211_tx_status: headroom too small
  ");
  		dev_kfree_skb(skb);
  		return;
  	}
a2fe81667   Helmut Schaa   mac80211: Build T...
561
  	ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len);
fe7a5d5c1   Johannes Berg   mac80211: move TX...
562
563
564
565
566
567
568
569
570
571
572
  
  	/* XXX: is this sufficient for BPF? */
  	skb_set_mac_header(skb, 0);
  	skb->ip_summed = CHECKSUM_UNNECESSARY;
  	skb->pkt_type = PACKET_OTHERHOST;
  	skb->protocol = htons(ETH_P_802_2);
  	memset(skb->cb, 0, sizeof(skb->cb));
  
  	rcu_read_lock();
  	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
  		if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
9607e6b66   Johannes Berg   mac80211: add iee...
573
  			if (!ieee80211_sdata_running(sdata))
fe7a5d5c1   Johannes Berg   mac80211: move TX...
574
575
576
  				continue;
  
  			if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
eaf55530c   Felix Fietkau   mac80211: optimiz...
577
  			    !send_to_cooked)
fe7a5d5c1   Johannes Berg   mac80211: move TX...
578
579
580
581
582
583
  				continue;
  
  			if (prev_dev) {
  				skb2 = skb_clone(skb, GFP_ATOMIC);
  				if (skb2) {
  					skb2->dev = prev_dev;
4efe7f51b   John W. Linville   Revert "mac80211:...
584
  					netif_rx(skb2);
fe7a5d5c1   Johannes Berg   mac80211: move TX...
585
586
587
588
589
590
591
592
  				}
  			}
  
  			prev_dev = sdata->dev;
  		}
  	}
  	if (prev_dev) {
  		skb->dev = prev_dev;
4efe7f51b   John W. Linville   Revert "mac80211:...
593
  		netif_rx(skb);
fe7a5d5c1   Johannes Berg   mac80211: move TX...
594
595
596
597
598
599
  		skb = NULL;
  	}
  	rcu_read_unlock();
  	dev_kfree_skb(skb);
  }
  EXPORT_SYMBOL(ieee80211_tx_status);
8178d38b7   Arik Nemtsov   mac80211: allow l...
600
601
602
603
604
605
606
607
  
  void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
  {
  	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
  	cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
  				    num_packets, GFP_ATOMIC);
  }
  EXPORT_SYMBOL(ieee80211_report_low_ack);
6096de7fd   Johannes Berg   mac80211: add hel...
608
609
610
  
  void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
  {
a729cff8a   Johannes Berg   mac80211: impleme...
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
  	struct ieee80211_local *local = hw_to_local(hw);
  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  
  	if (unlikely(info->ack_frame_id)) {
  		struct sk_buff *ack_skb;
  		unsigned long flags;
  
  		spin_lock_irqsave(&local->ack_status_lock, flags);
  		ack_skb = idr_find(&local->ack_status_frames,
  				   info->ack_frame_id);
  		if (ack_skb)
  			idr_remove(&local->ack_status_frames,
  				   info->ack_frame_id);
  		spin_unlock_irqrestore(&local->ack_status_lock, flags);
  
  		/* consumes ack_skb */
  		if (ack_skb)
  			dev_kfree_skb_any(ack_skb);
  	}
6096de7fd   Johannes Berg   mac80211: add hel...
630
631
632
  	dev_kfree_skb_any(skb);
  }
  EXPORT_SYMBOL(ieee80211_free_txskb);