]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - net/mac80211/agg-tx.c
mac80211: unify and fix TX aggregation start
[linux-2.6-omap-h63xx.git] / net / mac80211 / agg-tx.c
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 static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
408                                          struct sta_info *sta, u16 tid)
409 {
410 #ifdef CONFIG_MAC80211_HT_DEBUG
411         printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
412 #endif
413
414         if (local->hw.ampdu_queues) {
415                 /*
416                  * Wake up the A-MPDU queue, we stopped it earlier,
417                  * this will in turn wake the entire AC.
418                  */
419                 ieee80211_wake_queue_by_reason(&local->hw,
420                         local->hw.queues + sta->tid_to_tx_q[tid],
421                         IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
422         }
423
424         local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_OPERATIONAL,
425                                  &sta->sta, tid, NULL);
426 }
427
428 void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
429 {
430         struct ieee80211_local *local = hw_to_local(hw);
431         struct sta_info *sta;
432         u8 *state;
433
434         if (tid >= STA_TID_NUM) {
435 #ifdef CONFIG_MAC80211_HT_DEBUG
436                 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
437                                 tid, STA_TID_NUM);
438 #endif
439                 return;
440         }
441
442         rcu_read_lock();
443         sta = sta_info_get(local, ra);
444         if (!sta) {
445                 rcu_read_unlock();
446 #ifdef CONFIG_MAC80211_HT_DEBUG
447                 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
448 #endif
449                 return;
450         }
451
452         state = &sta->ampdu_mlme.tid_state_tx[tid];
453         spin_lock_bh(&sta->lock);
454
455         if (WARN_ON(!(*state & HT_ADDBA_REQUESTED_MSK))) {
456 #ifdef CONFIG_MAC80211_HT_DEBUG
457                 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
458                                 *state);
459 #endif
460                 spin_unlock_bh(&sta->lock);
461                 rcu_read_unlock();
462                 return;
463         }
464
465         if (WARN_ON(*state & HT_ADDBA_DRV_READY_MSK))
466                 goto out;
467
468         *state |= HT_ADDBA_DRV_READY_MSK;
469
470         if (*state == HT_AGG_STATE_OPERATIONAL)
471                 ieee80211_agg_tx_operational(local, sta, tid);
472
473  out:
474         spin_unlock_bh(&sta->lock);
475         rcu_read_unlock();
476 }
477 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
478
479 void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
480                                       const u8 *ra, u16 tid)
481 {
482         struct ieee80211_local *local = hw_to_local(hw);
483         struct ieee80211_ra_tid *ra_tid;
484         struct sk_buff *skb = dev_alloc_skb(0);
485
486         if (unlikely(!skb)) {
487 #ifdef CONFIG_MAC80211_HT_DEBUG
488                 if (net_ratelimit())
489                         printk(KERN_WARNING "%s: Not enough memory, "
490                                "dropping start BA session", skb->dev->name);
491 #endif
492                 return;
493         }
494         ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
495         memcpy(&ra_tid->ra, ra, ETH_ALEN);
496         ra_tid->tid = tid;
497
498         skb->pkt_type = IEEE80211_ADDBA_MSG;
499         skb_queue_tail(&local->skb_queue, skb);
500         tasklet_schedule(&local->tasklet);
501 }
502 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
503
504 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
505                                    enum ieee80211_back_parties initiator)
506 {
507         u8 *state;
508         int ret;
509
510         /* check if the TID is in aggregation */
511         state = &sta->ampdu_mlme.tid_state_tx[tid];
512         spin_lock_bh(&sta->lock);
513
514         if (*state != HT_AGG_STATE_OPERATIONAL) {
515                 ret = -ENOENT;
516                 goto unlock;
517         }
518
519 #ifdef CONFIG_MAC80211_HT_DEBUG
520         printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
521                sta->sta.addr, tid);
522 #endif /* CONFIG_MAC80211_HT_DEBUG */
523
524         ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
525
526  unlock:
527         spin_unlock_bh(&sta->lock);
528         return ret;
529 }
530
531 int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
532                                  u8 *ra, u16 tid,
533                                  enum ieee80211_back_parties initiator)
534 {
535         struct ieee80211_local *local = hw_to_local(hw);
536         struct sta_info *sta;
537         int ret = 0;
538
539         if (WARN_ON(!local->ops->ampdu_action))
540                 return -EINVAL;
541
542         if (tid >= STA_TID_NUM)
543                 return -EINVAL;
544
545         rcu_read_lock();
546         sta = sta_info_get(local, ra);
547         if (!sta) {
548                 rcu_read_unlock();
549                 return -ENOENT;
550         }
551
552         ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator);
553         rcu_read_unlock();
554         return ret;
555 }
556 EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
557
558 void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
559 {
560         struct ieee80211_local *local = hw_to_local(hw);
561         struct sta_info *sta;
562         u8 *state;
563
564         if (tid >= STA_TID_NUM) {
565 #ifdef CONFIG_MAC80211_HT_DEBUG
566                 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
567                                 tid, STA_TID_NUM);
568 #endif
569                 return;
570         }
571
572 #ifdef CONFIG_MAC80211_HT_DEBUG
573         printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
574                ra, tid);
575 #endif /* CONFIG_MAC80211_HT_DEBUG */
576
577         rcu_read_lock();
578         sta = sta_info_get(local, ra);
579         if (!sta) {
580 #ifdef CONFIG_MAC80211_HT_DEBUG
581                 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
582 #endif
583                 rcu_read_unlock();
584                 return;
585         }
586         state = &sta->ampdu_mlme.tid_state_tx[tid];
587
588         /* NOTE: no need to use sta->lock in this state check, as
589          * ieee80211_stop_tx_ba_session will let only one stop call to
590          * pass through per sta/tid
591          */
592         if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
593 #ifdef CONFIG_MAC80211_HT_DEBUG
594                 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
595 #endif
596                 rcu_read_unlock();
597                 return;
598         }
599
600         if (*state & HT_AGG_STATE_INITIATOR_MSK)
601                 ieee80211_send_delba(sta->sdata, ra, tid,
602                         WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
603
604         spin_lock_bh(&sta->lock);
605
606         if (*state & HT_AGG_STATE_INITIATOR_MSK &&
607             hw->ampdu_queues) {
608                 /*
609                  * Wake up this queue, we stopped it earlier,
610                  * this will in turn wake the entire AC.
611                  */
612                 ieee80211_wake_queue_by_reason(hw,
613                         hw->queues + sta->tid_to_tx_q[tid],
614                         IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
615         }
616
617         *state = HT_AGG_STATE_IDLE;
618         sta->ampdu_mlme.addba_req_num[tid] = 0;
619         kfree(sta->ampdu_mlme.tid_tx[tid]);
620         sta->ampdu_mlme.tid_tx[tid] = NULL;
621         spin_unlock_bh(&sta->lock);
622
623         rcu_read_unlock();
624 }
625 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
626
627 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
628                                      const u8 *ra, u16 tid)
629 {
630         struct ieee80211_local *local = hw_to_local(hw);
631         struct ieee80211_ra_tid *ra_tid;
632         struct sk_buff *skb = dev_alloc_skb(0);
633
634         if (unlikely(!skb)) {
635 #ifdef CONFIG_MAC80211_HT_DEBUG
636                 if (net_ratelimit())
637                         printk(KERN_WARNING "%s: Not enough memory, "
638                                "dropping stop BA session", skb->dev->name);
639 #endif
640                 return;
641         }
642         ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
643         memcpy(&ra_tid->ra, ra, ETH_ALEN);
644         ra_tid->tid = tid;
645
646         skb->pkt_type = IEEE80211_DELBA_MSG;
647         skb_queue_tail(&local->skb_queue, skb);
648         tasklet_schedule(&local->tasklet);
649 }
650 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
651
652
653 void ieee80211_process_addba_resp(struct ieee80211_local *local,
654                                   struct sta_info *sta,
655                                   struct ieee80211_mgmt *mgmt,
656                                   size_t len)
657 {
658         u16 capab, tid;
659         u8 *state;
660
661         capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
662         tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
663
664         state = &sta->ampdu_mlme.tid_state_tx[tid];
665
666         spin_lock_bh(&sta->lock);
667
668         if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
669                 spin_unlock_bh(&sta->lock);
670                 return;
671         }
672
673         if (mgmt->u.action.u.addba_resp.dialog_token !=
674                 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
675                 spin_unlock_bh(&sta->lock);
676 #ifdef CONFIG_MAC80211_HT_DEBUG
677                 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
678 #endif /* CONFIG_MAC80211_HT_DEBUG */
679                 return;
680         }
681
682         del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
683 #ifdef CONFIG_MAC80211_HT_DEBUG
684         printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
685 #endif /* CONFIG_MAC80211_HT_DEBUG */
686         if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
687                         == WLAN_STATUS_SUCCESS) {
688                 u8 curstate = *state;
689
690                 *state |= HT_ADDBA_RECEIVED_MSK;
691
692                 if (*state != curstate && *state == HT_AGG_STATE_OPERATIONAL)
693                         ieee80211_agg_tx_operational(local, sta, tid);
694
695                 sta->ampdu_mlme.addba_req_num[tid] = 0;
696         } else {
697                 sta->ampdu_mlme.addba_req_num[tid]++;
698                 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
699         }
700         spin_unlock_bh(&sta->lock);
701 }