xref: /openbmc/linux/net/mac80211/agg-tx.c (revision 722f069a)
1 /*
2  * HT handling
3  *
4  * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5  * Copyright 2002-2005, Instant802 Networks, Inc.
6  * Copyright 2005-2006, Devicescape Software, Inc.
7  * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
8  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9  * Copyright 2007-2009, Intel Corporation
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15 
16 #include <linux/ieee80211.h>
17 #include <net/mac80211.h>
18 #include "ieee80211_i.h"
19 #include "wme.h"
20 
21 /**
22  * DOC: TX aggregation
23  *
24  * Aggregation on the TX side requires setting the hardware flag
25  * %IEEE80211_HW_AMPDU_AGGREGATION as well as, if present, the @ampdu_queues
26  * hardware parameter to the number of hardware AMPDU queues. If there are no
27  * hardware queues then the driver will (currently) have to do all frame
28  * buffering.
29  *
30  * When TX aggregation is started by some subsystem (usually the rate control
31  * algorithm would be appropriate) by calling the
32  * ieee80211_start_tx_ba_session() function, the driver will be notified via
33  * its @ampdu_action function, with the %IEEE80211_AMPDU_TX_START action.
34  *
35  * In response to that, the driver is later required to call the
36  * ieee80211_start_tx_ba_cb() (or ieee80211_start_tx_ba_cb_irqsafe())
37  * function, which will start the aggregation session.
38  *
39  * Similarly, when the aggregation session is stopped by
40  * ieee80211_stop_tx_ba_session(), the driver's @ampdu_action function will
41  * be called with the action %IEEE80211_AMPDU_TX_STOP. In this case, the
42  * call must not fail, and the driver must later call ieee80211_stop_tx_ba_cb()
43  * (or ieee80211_stop_tx_ba_cb_irqsafe()).
44  */
45 
46 static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
47 					 const u8 *da, u16 tid,
48 					 u8 dialog_token, u16 start_seq_num,
49 					 u16 agg_size, u16 timeout)
50 {
51 	struct ieee80211_local *local = sdata->local;
52 	struct sk_buff *skb;
53 	struct ieee80211_mgmt *mgmt;
54 	u16 capab;
55 
56 	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
57 
58 	if (!skb) {
59 		printk(KERN_ERR "%s: failed to allocate buffer "
60 				"for addba request frame\n", sdata->dev->name);
61 		return;
62 	}
63 	skb_reserve(skb, local->hw.extra_tx_headroom);
64 	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
65 	memset(mgmt, 0, 24);
66 	memcpy(mgmt->da, da, ETH_ALEN);
67 	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
68 	if (sdata->vif.type == NL80211_IFTYPE_AP ||
69 	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
70 		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
71 	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
72 		memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
73 
74 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
75 					  IEEE80211_STYPE_ACTION);
76 
77 	skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
78 
79 	mgmt->u.action.category = WLAN_CATEGORY_BACK;
80 	mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
81 
82 	mgmt->u.action.u.addba_req.dialog_token = dialog_token;
83 	capab = (u16)(1 << 1);		/* bit 1 aggregation policy */
84 	capab |= (u16)(tid << 2); 	/* bit 5:2 TID number */
85 	capab |= (u16)(agg_size << 6);	/* bit 15:6 max size of aggergation */
86 
87 	mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
88 
89 	mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
90 	mgmt->u.action.u.addba_req.start_seq_num =
91 					cpu_to_le16(start_seq_num << 4);
92 
93 	ieee80211_tx_skb(sdata, skb, 1);
94 }
95 
96 void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
97 {
98 	struct ieee80211_local *local = sdata->local;
99 	struct sk_buff *skb;
100 	struct ieee80211_bar *bar;
101 	u16 bar_control = 0;
102 
103 	skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
104 	if (!skb) {
105 		printk(KERN_ERR "%s: failed to allocate buffer for "
106 			"bar frame\n", sdata->dev->name);
107 		return;
108 	}
109 	skb_reserve(skb, local->hw.extra_tx_headroom);
110 	bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
111 	memset(bar, 0, sizeof(*bar));
112 	bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
113 					 IEEE80211_STYPE_BACK_REQ);
114 	memcpy(bar->ra, ra, ETH_ALEN);
115 	memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
116 	bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
117 	bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
118 	bar_control |= (u16)(tid << 12);
119 	bar->control = cpu_to_le16(bar_control);
120 	bar->start_seq_num = cpu_to_le16(ssn);
121 
122 	ieee80211_tx_skb(sdata, skb, 0);
123 }
124 
125 static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
126 					   enum ieee80211_back_parties initiator)
127 {
128 	struct ieee80211_local *local = sta->local;
129 	int ret;
130 	u8 *state;
131 
132 	state = &sta->ampdu_mlme.tid_state_tx[tid];
133 
134 	if (local->hw.ampdu_queues) {
135 		if (initiator) {
136 			/*
137 			 * Stop the AC queue to avoid issues where we send
138 			 * unaggregated frames already before the delba.
139 			 */
140 			ieee80211_stop_queue_by_reason(&local->hw,
141 				local->hw.queues + sta->tid_to_tx_q[tid],
142 				IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
143 		}
144 
145 		/*
146 		 * Pretend the driver woke the queue, just in case
147 		 * it disabled it before the session was stopped.
148 		 */
149 		ieee80211_wake_queue(
150 			&local->hw, local->hw.queues + sta->tid_to_tx_q[tid]);
151 	}
152 	*state = HT_AGG_STATE_REQ_STOP_BA_MSK |
153 		(initiator << HT_AGG_STATE_INITIATOR_SHIFT);
154 
155 	ret = local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_STOP,
156 				       &sta->sta, tid, NULL);
157 
158 	/* HW shall not deny going back to legacy */
159 	if (WARN_ON(ret)) {
160 		*state = HT_AGG_STATE_OPERATIONAL;
161 	}
162 
163 	return ret;
164 }
165 
166 /*
167  * After sending add Block Ack request we activated a timer until
168  * add Block Ack response will arrive from the recipient.
169  * If this timer expires sta_addba_resp_timer_expired will be executed.
170  */
171 static void sta_addba_resp_timer_expired(unsigned long data)
172 {
173 	/* not an elegant detour, but there is no choice as the timer passes
174 	 * only one argument, and both sta_info and TID are needed, so init
175 	 * flow in sta_info_create gives the TID as data, while the timer_to_id
176 	 * array gives the sta through container_of */
177 	u16 tid = *(u8 *)data;
178 	struct sta_info *sta = container_of((void *)data,
179 		struct sta_info, timer_to_tid[tid]);
180 	u8 *state;
181 
182 	state = &sta->ampdu_mlme.tid_state_tx[tid];
183 
184 	/* check if the TID waits for addBA response */
185 	spin_lock_bh(&sta->lock);
186 	if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
187 		spin_unlock_bh(&sta->lock);
188 		*state = HT_AGG_STATE_IDLE;
189 #ifdef CONFIG_MAC80211_HT_DEBUG
190 		printk(KERN_DEBUG "timer expired on tid %d but we are not "
191 				"expecting addBA response there", tid);
192 #endif
193 		return;
194 	}
195 
196 #ifdef CONFIG_MAC80211_HT_DEBUG
197 	printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
198 #endif
199 
200 	___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
201 	spin_unlock_bh(&sta->lock);
202 }
203 
204 static inline int ieee80211_ac_from_tid(int tid)
205 {
206 	return ieee802_1d_to_ac[tid & 7];
207 }
208 
209 int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
210 {
211 	struct ieee80211_local *local = hw_to_local(hw);
212 	struct sta_info *sta;
213 	struct ieee80211_sub_if_data *sdata;
214 	u8 *state;
215 	int i, qn = -1, ret = 0;
216 	u16 start_seq_num;
217 
218 	if (WARN_ON(!local->ops->ampdu_action))
219 		return -EINVAL;
220 
221 	if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
222 		return -EINVAL;
223 
224 #ifdef CONFIG_MAC80211_HT_DEBUG
225 	printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
226 	       ra, tid);
227 #endif /* CONFIG_MAC80211_HT_DEBUG */
228 
229 	if (hw->ampdu_queues && ieee80211_ac_from_tid(tid) == 0) {
230 #ifdef CONFIG_MAC80211_HT_DEBUG
231 		printk(KERN_DEBUG "rejecting on voice AC\n");
232 #endif
233 		return -EINVAL;
234 	}
235 
236 	rcu_read_lock();
237 
238 	sta = sta_info_get(local, ra);
239 	if (!sta) {
240 #ifdef CONFIG_MAC80211_HT_DEBUG
241 		printk(KERN_DEBUG "Could not find the station\n");
242 #endif
243 		ret = -ENOENT;
244 		goto unlock;
245 	}
246 
247 	/*
248 	 * The aggregation code is not prepared to handle
249 	 * anything but STA/AP due to the BSSID handling.
250 	 * IBSS could work in the code but isn't supported
251 	 * by drivers or the standard.
252 	 */
253 	if (sta->sdata->vif.type != NL80211_IFTYPE_STATION &&
254 	    sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
255 	    sta->sdata->vif.type != NL80211_IFTYPE_AP) {
256 		ret = -EINVAL;
257 		goto unlock;
258 	}
259 
260 	if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
261 #ifdef CONFIG_MAC80211_HT_DEBUG
262 		printk(KERN_DEBUG "Suspend in progress. "
263 		       "Denying BA session request\n");
264 #endif
265 		ret = -EINVAL;
266 		goto unlock;
267 	}
268 
269 	spin_lock_bh(&sta->lock);
270 
271 	sdata = sta->sdata;
272 
273 	/* we have tried too many times, receiver does not want A-MPDU */
274 	if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
275 		ret = -EBUSY;
276 		goto err_unlock_sta;
277 	}
278 
279 	state = &sta->ampdu_mlme.tid_state_tx[tid];
280 	/* check if the TID is not in aggregation flow already */
281 	if (*state != HT_AGG_STATE_IDLE) {
282 #ifdef CONFIG_MAC80211_HT_DEBUG
283 		printk(KERN_DEBUG "BA request denied - session is not "
284 				 "idle on tid %u\n", tid);
285 #endif /* CONFIG_MAC80211_HT_DEBUG */
286 		ret = -EAGAIN;
287 		goto err_unlock_sta;
288 	}
289 
290 	if (hw->ampdu_queues) {
291 		spin_lock(&local->queue_stop_reason_lock);
292 		/* reserve a new queue for this session */
293 		for (i = 0; i < local->hw.ampdu_queues; i++) {
294 			if (local->ampdu_ac_queue[i] < 0) {
295 				qn = i;
296 				local->ampdu_ac_queue[qn] =
297 					ieee80211_ac_from_tid(tid);
298 				break;
299 			}
300 		}
301 		spin_unlock(&local->queue_stop_reason_lock);
302 
303 		if (qn < 0) {
304 #ifdef CONFIG_MAC80211_HT_DEBUG
305 			printk(KERN_DEBUG "BA request denied - "
306 			       "queue unavailable for tid %d\n", tid);
307 #endif /* CONFIG_MAC80211_HT_DEBUG */
308 			ret = -ENOSPC;
309 			goto err_unlock_sta;
310 		}
311 
312 		/*
313 		 * If we successfully allocate the session, we can't have
314 		 * anything going on on the queue this TID maps into, so
315 		 * stop it for now. This is a "virtual" stop using the same
316 		 * mechanism that drivers will use.
317 		 *
318 		 * XXX: queue up frames for this session in the sta_info
319 		 *	struct instead to avoid hitting all other STAs.
320 		 */
321 		ieee80211_stop_queue_by_reason(
322 			&local->hw, hw->queues + qn,
323 			IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
324 	}
325 
326 	/* prepare A-MPDU MLME for Tx aggregation */
327 	sta->ampdu_mlme.tid_tx[tid] =
328 			kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
329 	if (!sta->ampdu_mlme.tid_tx[tid]) {
330 #ifdef CONFIG_MAC80211_HT_DEBUG
331 		if (net_ratelimit())
332 			printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
333 					tid);
334 #endif
335 		ret = -ENOMEM;
336 		goto err_return_queue;
337 	}
338 
339 	/* Tx timer */
340 	sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
341 			sta_addba_resp_timer_expired;
342 	sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
343 			(unsigned long)&sta->timer_to_tid[tid];
344 	init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
345 
346 	/* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
347 	 * call back right away, it must see that the flow has begun */
348 	*state |= HT_ADDBA_REQUESTED_MSK;
349 
350 	start_seq_num = sta->tid_seq[tid];
351 
352 	ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
353 				       &sta->sta, tid, &start_seq_num);
354 
355 	if (ret) {
356 #ifdef CONFIG_MAC80211_HT_DEBUG
357 		printk(KERN_DEBUG "BA request denied - HW unavailable for"
358 					" tid %d\n", tid);
359 #endif /* CONFIG_MAC80211_HT_DEBUG */
360 		*state = HT_AGG_STATE_IDLE;
361 		goto err_free;
362 	}
363 	sta->tid_to_tx_q[tid] = qn;
364 
365 	spin_unlock_bh(&sta->lock);
366 
367 	/* send an addBA request */
368 	sta->ampdu_mlme.dialog_token_allocator++;
369 	sta->ampdu_mlme.tid_tx[tid]->dialog_token =
370 			sta->ampdu_mlme.dialog_token_allocator;
371 	sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
372 
373 	ieee80211_send_addba_request(sta->sdata, ra, tid,
374 			 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
375 			 sta->ampdu_mlme.tid_tx[tid]->ssn,
376 			 0x40, 5000);
377 	/* activate the timer for the recipient's addBA response */
378 	sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
379 				jiffies + ADDBA_RESP_INTERVAL;
380 	add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
381 #ifdef CONFIG_MAC80211_HT_DEBUG
382 	printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
383 #endif
384 	goto unlock;
385 
386  err_free:
387 	kfree(sta->ampdu_mlme.tid_tx[tid]);
388 	sta->ampdu_mlme.tid_tx[tid] = NULL;
389  err_return_queue:
390 	if (qn >= 0) {
391 		/* We failed, so start queue again right away. */
392 		ieee80211_wake_queue_by_reason(hw, hw->queues + qn,
393 			IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
394 		/* give queue back to pool */
395 		spin_lock(&local->queue_stop_reason_lock);
396 		local->ampdu_ac_queue[qn] = -1;
397 		spin_unlock(&local->queue_stop_reason_lock);
398 	}
399  err_unlock_sta:
400 	spin_unlock_bh(&sta->lock);
401  unlock:
402 	rcu_read_unlock();
403 	return ret;
404 }
405 EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
406 
407 void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
408 {
409 	struct ieee80211_local *local = hw_to_local(hw);
410 	struct sta_info *sta;
411 	u8 *state;
412 
413 	if (tid >= STA_TID_NUM) {
414 #ifdef CONFIG_MAC80211_HT_DEBUG
415 		printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
416 				tid, STA_TID_NUM);
417 #endif
418 		return;
419 	}
420 
421 	rcu_read_lock();
422 	sta = sta_info_get(local, ra);
423 	if (!sta) {
424 		rcu_read_unlock();
425 #ifdef CONFIG_MAC80211_HT_DEBUG
426 		printk(KERN_DEBUG "Could not find station: %pM\n", ra);
427 #endif
428 		return;
429 	}
430 
431 	state = &sta->ampdu_mlme.tid_state_tx[tid];
432 	spin_lock_bh(&sta->lock);
433 
434 	if (WARN_ON(!(*state & HT_ADDBA_REQUESTED_MSK))) {
435 #ifdef CONFIG_MAC80211_HT_DEBUG
436 		printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
437 				*state);
438 #endif
439 		spin_unlock_bh(&sta->lock);
440 		rcu_read_unlock();
441 		return;
442 	}
443 
444 	if (WARN_ON(*state & HT_ADDBA_DRV_READY_MSK))
445 		goto out;
446 
447 	*state |= HT_ADDBA_DRV_READY_MSK;
448 
449 	if (*state == HT_AGG_STATE_OPERATIONAL) {
450 #ifdef CONFIG_MAC80211_HT_DEBUG
451 		printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
452 #endif
453 		if (hw->ampdu_queues) {
454 			/*
455 			 * Wake up this queue, we stopped it earlier,
456 			 * this will in turn wake the entire AC.
457 			 */
458 			ieee80211_wake_queue_by_reason(hw,
459 				hw->queues + sta->tid_to_tx_q[tid],
460 				IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
461 		}
462 	}
463 
464  out:
465 	spin_unlock_bh(&sta->lock);
466 	rcu_read_unlock();
467 }
468 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
469 
470 void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
471 				      const u8 *ra, u16 tid)
472 {
473 	struct ieee80211_local *local = hw_to_local(hw);
474 	struct ieee80211_ra_tid *ra_tid;
475 	struct sk_buff *skb = dev_alloc_skb(0);
476 
477 	if (unlikely(!skb)) {
478 #ifdef CONFIG_MAC80211_HT_DEBUG
479 		if (net_ratelimit())
480 			printk(KERN_WARNING "%s: Not enough memory, "
481 			       "dropping start BA session", skb->dev->name);
482 #endif
483 		return;
484 	}
485 	ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
486 	memcpy(&ra_tid->ra, ra, ETH_ALEN);
487 	ra_tid->tid = tid;
488 
489 	skb->pkt_type = IEEE80211_ADDBA_MSG;
490 	skb_queue_tail(&local->skb_queue, skb);
491 	tasklet_schedule(&local->tasklet);
492 }
493 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
494 
495 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
496 				   enum ieee80211_back_parties initiator)
497 {
498 	u8 *state;
499 	int ret;
500 
501 	/* check if the TID is in aggregation */
502 	state = &sta->ampdu_mlme.tid_state_tx[tid];
503 	spin_lock_bh(&sta->lock);
504 
505 	if (*state != HT_AGG_STATE_OPERATIONAL) {
506 		ret = -ENOENT;
507 		goto unlock;
508 	}
509 
510 #ifdef CONFIG_MAC80211_HT_DEBUG
511 	printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
512 	       sta->sta.addr, tid);
513 #endif /* CONFIG_MAC80211_HT_DEBUG */
514 
515 	ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
516 
517  unlock:
518 	spin_unlock_bh(&sta->lock);
519 	return ret;
520 }
521 
522 int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
523 				 u8 *ra, u16 tid,
524 				 enum ieee80211_back_parties initiator)
525 {
526 	struct ieee80211_local *local = hw_to_local(hw);
527 	struct sta_info *sta;
528 	int ret = 0;
529 
530 	if (WARN_ON(!local->ops->ampdu_action))
531 		return -EINVAL;
532 
533 	if (tid >= STA_TID_NUM)
534 		return -EINVAL;
535 
536 	rcu_read_lock();
537 	sta = sta_info_get(local, ra);
538 	if (!sta) {
539 		rcu_read_unlock();
540 		return -ENOENT;
541 	}
542 
543 	ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator);
544 	rcu_read_unlock();
545 	return ret;
546 }
547 EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
548 
549 void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
550 {
551 	struct ieee80211_local *local = hw_to_local(hw);
552 	struct sta_info *sta;
553 	u8 *state;
554 
555 	if (tid >= STA_TID_NUM) {
556 #ifdef CONFIG_MAC80211_HT_DEBUG
557 		printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
558 				tid, STA_TID_NUM);
559 #endif
560 		return;
561 	}
562 
563 #ifdef CONFIG_MAC80211_HT_DEBUG
564 	printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
565 	       ra, tid);
566 #endif /* CONFIG_MAC80211_HT_DEBUG */
567 
568 	rcu_read_lock();
569 	sta = sta_info_get(local, ra);
570 	if (!sta) {
571 #ifdef CONFIG_MAC80211_HT_DEBUG
572 		printk(KERN_DEBUG "Could not find station: %pM\n", ra);
573 #endif
574 		rcu_read_unlock();
575 		return;
576 	}
577 	state = &sta->ampdu_mlme.tid_state_tx[tid];
578 
579 	/* NOTE: no need to use sta->lock in this state check, as
580 	 * ieee80211_stop_tx_ba_session will let only one stop call to
581 	 * pass through per sta/tid
582 	 */
583 	if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
584 #ifdef CONFIG_MAC80211_HT_DEBUG
585 		printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
586 #endif
587 		rcu_read_unlock();
588 		return;
589 	}
590 
591 	if (*state & HT_AGG_STATE_INITIATOR_MSK)
592 		ieee80211_send_delba(sta->sdata, ra, tid,
593 			WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
594 
595 	spin_lock_bh(&sta->lock);
596 
597 	if (*state & HT_AGG_STATE_INITIATOR_MSK &&
598 	    hw->ampdu_queues) {
599 		/*
600 		 * Wake up this queue, we stopped it earlier,
601 		 * this will in turn wake the entire AC.
602 		 */
603 		ieee80211_wake_queue_by_reason(hw,
604 			hw->queues + sta->tid_to_tx_q[tid],
605 			IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
606 	}
607 
608 	*state = HT_AGG_STATE_IDLE;
609 	sta->ampdu_mlme.addba_req_num[tid] = 0;
610 	kfree(sta->ampdu_mlme.tid_tx[tid]);
611 	sta->ampdu_mlme.tid_tx[tid] = NULL;
612 	spin_unlock_bh(&sta->lock);
613 
614 	rcu_read_unlock();
615 }
616 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
617 
618 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
619 				     const u8 *ra, u16 tid)
620 {
621 	struct ieee80211_local *local = hw_to_local(hw);
622 	struct ieee80211_ra_tid *ra_tid;
623 	struct sk_buff *skb = dev_alloc_skb(0);
624 
625 	if (unlikely(!skb)) {
626 #ifdef CONFIG_MAC80211_HT_DEBUG
627 		if (net_ratelimit())
628 			printk(KERN_WARNING "%s: Not enough memory, "
629 			       "dropping stop BA session", skb->dev->name);
630 #endif
631 		return;
632 	}
633 	ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
634 	memcpy(&ra_tid->ra, ra, ETH_ALEN);
635 	ra_tid->tid = tid;
636 
637 	skb->pkt_type = IEEE80211_DELBA_MSG;
638 	skb_queue_tail(&local->skb_queue, skb);
639 	tasklet_schedule(&local->tasklet);
640 }
641 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
642 
643 
644 void ieee80211_process_addba_resp(struct ieee80211_local *local,
645 				  struct sta_info *sta,
646 				  struct ieee80211_mgmt *mgmt,
647 				  size_t len)
648 {
649 	struct ieee80211_hw *hw = &local->hw;
650 	u16 capab;
651 	u16 tid, start_seq_num;
652 	u8 *state;
653 
654 	capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
655 	tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
656 
657 	state = &sta->ampdu_mlme.tid_state_tx[tid];
658 
659 	spin_lock_bh(&sta->lock);
660 
661 	if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
662 		spin_unlock_bh(&sta->lock);
663 		return;
664 	}
665 
666 	if (mgmt->u.action.u.addba_resp.dialog_token !=
667 		sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
668 		spin_unlock_bh(&sta->lock);
669 #ifdef CONFIG_MAC80211_HT_DEBUG
670 		printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
671 #endif /* CONFIG_MAC80211_HT_DEBUG */
672 		return;
673 	}
674 
675 	del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
676 #ifdef CONFIG_MAC80211_HT_DEBUG
677 	printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
678 #endif /* CONFIG_MAC80211_HT_DEBUG */
679 	if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
680 			== WLAN_STATUS_SUCCESS) {
681 		u8 curstate = *state;
682 
683 		*state |= HT_ADDBA_RECEIVED_MSK;
684 
685 		if (hw->ampdu_queues && *state != curstate &&
686 		    *state == HT_AGG_STATE_OPERATIONAL) {
687 			/*
688 			 * Wake up this queue, we stopped it earlier,
689 			 * this will in turn wake the entire AC.
690 			 */
691 			ieee80211_wake_queue_by_reason(hw,
692 				hw->queues + sta->tid_to_tx_q[tid],
693 				IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
694 		}
695 		sta->ampdu_mlme.addba_req_num[tid] = 0;
696 
697 		if (local->ops->ampdu_action) {
698 			(void)local->ops->ampdu_action(hw,
699 					       IEEE80211_AMPDU_TX_RESUME,
700 					       &sta->sta, tid, &start_seq_num);
701 		}
702 #ifdef CONFIG_MAC80211_HT_DEBUG
703 		printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
704 #endif /* CONFIG_MAC80211_HT_DEBUG */
705 	} else {
706 		sta->ampdu_mlme.addba_req_num[tid]++;
707 		___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
708 	}
709 	spin_unlock_bh(&sta->lock);
710 }
711