]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - net/mac80211/agg-tx.c
mac80211: Tear down aggregation sessions for suspend/resume
[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 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 }