mac80211: restructure HT code
[safe/jmp/linux-2.6] / 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 static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
22                                          const u8 *da, u16 tid,
23                                          u8 dialog_token, u16 start_seq_num,
24                                          u16 agg_size, u16 timeout)
25 {
26         struct ieee80211_local *local = sdata->local;
27         struct ieee80211_if_sta *ifsta = &sdata->u.sta;
28         struct sk_buff *skb;
29         struct ieee80211_mgmt *mgmt;
30         u16 capab;
31
32         skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
33
34         if (!skb) {
35                 printk(KERN_ERR "%s: failed to allocate buffer "
36                                 "for addba request frame\n", sdata->dev->name);
37                 return;
38         }
39         skb_reserve(skb, local->hw.extra_tx_headroom);
40         mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
41         memset(mgmt, 0, 24);
42         memcpy(mgmt->da, da, ETH_ALEN);
43         memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
44         if (sdata->vif.type == NL80211_IFTYPE_AP)
45                 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
46         else
47                 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
48
49         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
50                                           IEEE80211_STYPE_ACTION);
51
52         skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
53
54         mgmt->u.action.category = WLAN_CATEGORY_BACK;
55         mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
56
57         mgmt->u.action.u.addba_req.dialog_token = dialog_token;
58         capab = (u16)(1 << 1);          /* bit 1 aggregation policy */
59         capab |= (u16)(tid << 2);       /* bit 5:2 TID number */
60         capab |= (u16)(agg_size << 6);  /* bit 15:6 max size of aggergation */
61
62         mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
63
64         mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
65         mgmt->u.action.u.addba_req.start_seq_num =
66                                         cpu_to_le16(start_seq_num << 4);
67
68         ieee80211_tx_skb(sdata, skb, 1);
69 }
70
71 void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
72 {
73         struct ieee80211_local *local = sdata->local;
74         struct sk_buff *skb;
75         struct ieee80211_bar *bar;
76         u16 bar_control = 0;
77
78         skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
79         if (!skb) {
80                 printk(KERN_ERR "%s: failed to allocate buffer for "
81                         "bar frame\n", sdata->dev->name);
82                 return;
83         }
84         skb_reserve(skb, local->hw.extra_tx_headroom);
85         bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
86         memset(bar, 0, sizeof(*bar));
87         bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
88                                          IEEE80211_STYPE_BACK_REQ);
89         memcpy(bar->ra, ra, ETH_ALEN);
90         memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
91         bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
92         bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
93         bar_control |= (u16)(tid << 12);
94         bar->control = cpu_to_le16(bar_control);
95         bar->start_seq_num = cpu_to_le16(ssn);
96
97         ieee80211_tx_skb(sdata, skb, 0);
98 }
99
100 /*
101  * After sending add Block Ack request we activated a timer until
102  * add Block Ack response will arrive from the recipient.
103  * If this timer expires sta_addba_resp_timer_expired will be executed.
104  */
105 static void sta_addba_resp_timer_expired(unsigned long data)
106 {
107         /* not an elegant detour, but there is no choice as the timer passes
108          * only one argument, and both sta_info and TID are needed, so init
109          * flow in sta_info_create gives the TID as data, while the timer_to_id
110          * array gives the sta through container_of */
111         u16 tid = *(u8 *)data;
112         struct sta_info *temp_sta = container_of((void *)data,
113                 struct sta_info, timer_to_tid[tid]);
114
115         struct ieee80211_local *local = temp_sta->local;
116         struct ieee80211_hw *hw = &local->hw;
117         struct sta_info *sta;
118         u8 *state;
119
120         rcu_read_lock();
121
122         sta = sta_info_get(local, temp_sta->sta.addr);
123         if (!sta) {
124                 rcu_read_unlock();
125                 return;
126         }
127
128         state = &sta->ampdu_mlme.tid_state_tx[tid];
129         /* check if the TID waits for addBA response */
130         spin_lock_bh(&sta->lock);
131         if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
132                 spin_unlock_bh(&sta->lock);
133                 *state = HT_AGG_STATE_IDLE;
134 #ifdef CONFIG_MAC80211_HT_DEBUG
135                 printk(KERN_DEBUG "timer expired on tid %d but we are not "
136                                 "expecting addBA response there", tid);
137 #endif
138                 goto timer_expired_exit;
139         }
140
141 #ifdef CONFIG_MAC80211_HT_DEBUG
142         printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
143 #endif
144
145         /* go through the state check in stop_BA_session */
146         *state = HT_AGG_STATE_OPERATIONAL;
147         spin_unlock_bh(&sta->lock);
148         ieee80211_stop_tx_ba_session(hw, temp_sta->sta.addr, tid,
149                                      WLAN_BACK_INITIATOR);
150
151 timer_expired_exit:
152         rcu_read_unlock();
153 }
154
155 int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
156 {
157         struct ieee80211_local *local = hw_to_local(hw);
158         struct sta_info *sta;
159         struct ieee80211_sub_if_data *sdata;
160         u16 start_seq_num;
161         u8 *state;
162         int ret = 0;
163
164         if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
165                 return -EINVAL;
166
167 #ifdef CONFIG_MAC80211_HT_DEBUG
168         printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
169                ra, tid);
170 #endif /* CONFIG_MAC80211_HT_DEBUG */
171
172         rcu_read_lock();
173
174         sta = sta_info_get(local, ra);
175         if (!sta) {
176 #ifdef CONFIG_MAC80211_HT_DEBUG
177                 printk(KERN_DEBUG "Could not find the station\n");
178 #endif
179                 ret = -ENOENT;
180                 goto exit;
181         }
182
183         spin_lock_bh(&sta->lock);
184
185         /* we have tried too many times, receiver does not want A-MPDU */
186         if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
187                 ret = -EBUSY;
188                 goto err_unlock_sta;
189         }
190
191         state = &sta->ampdu_mlme.tid_state_tx[tid];
192         /* check if the TID is not in aggregation flow already */
193         if (*state != HT_AGG_STATE_IDLE) {
194 #ifdef CONFIG_MAC80211_HT_DEBUG
195                 printk(KERN_DEBUG "BA request denied - session is not "
196                                  "idle on tid %u\n", tid);
197 #endif /* CONFIG_MAC80211_HT_DEBUG */
198                 ret = -EAGAIN;
199                 goto err_unlock_sta;
200         }
201
202         /* prepare A-MPDU MLME for Tx aggregation */
203         sta->ampdu_mlme.tid_tx[tid] =
204                         kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
205         if (!sta->ampdu_mlme.tid_tx[tid]) {
206 #ifdef CONFIG_MAC80211_HT_DEBUG
207                 if (net_ratelimit())
208                         printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
209                                         tid);
210 #endif
211                 ret = -ENOMEM;
212                 goto err_unlock_sta;
213         }
214         /* Tx timer */
215         sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
216                         sta_addba_resp_timer_expired;
217         sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
218                         (unsigned long)&sta->timer_to_tid[tid];
219         init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
220
221         if (hw->ampdu_queues) {
222                 /* create a new queue for this aggregation */
223                 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
224
225                 /* case no queue is available to aggregation
226                  * don't switch to aggregation */
227                 if (ret) {
228 #ifdef CONFIG_MAC80211_HT_DEBUG
229                         printk(KERN_DEBUG "BA request denied - "
230                                "queue unavailable for tid %d\n", tid);
231 #endif /* CONFIG_MAC80211_HT_DEBUG */
232                         goto err_unlock_queue;
233                 }
234         }
235         sdata = sta->sdata;
236
237         /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
238          * call back right away, it must see that the flow has begun */
239         *state |= HT_ADDBA_REQUESTED_MSK;
240
241         /* This is slightly racy because the queue isn't stopped */
242         start_seq_num = sta->tid_seq[tid];
243
244         if (local->ops->ampdu_action)
245                 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
246                                                &sta->sta, tid, &start_seq_num);
247
248         if (ret) {
249                 /* No need to requeue the packets in the agg queue, since we
250                  * held the tx lock: no packet could be enqueued to the newly
251                  * allocated queue */
252                 if (hw->ampdu_queues)
253                         ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
254 #ifdef CONFIG_MAC80211_HT_DEBUG
255                 printk(KERN_DEBUG "BA request denied - HW unavailable for"
256                                         " tid %d\n", tid);
257 #endif /* CONFIG_MAC80211_HT_DEBUG */
258                 *state = HT_AGG_STATE_IDLE;
259                 goto err_unlock_queue;
260         }
261
262         /* Will put all the packets in the new SW queue */
263         if (hw->ampdu_queues)
264                 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
265         spin_unlock_bh(&sta->lock);
266
267         /* send an addBA request */
268         sta->ampdu_mlme.dialog_token_allocator++;
269         sta->ampdu_mlme.tid_tx[tid]->dialog_token =
270                         sta->ampdu_mlme.dialog_token_allocator;
271         sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
272
273
274         ieee80211_send_addba_request(sta->sdata, ra, tid,
275                          sta->ampdu_mlme.tid_tx[tid]->dialog_token,
276                          sta->ampdu_mlme.tid_tx[tid]->ssn,
277                          0x40, 5000);
278         /* activate the timer for the recipient's addBA response */
279         sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
280                                 jiffies + ADDBA_RESP_INTERVAL;
281         add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
282 #ifdef CONFIG_MAC80211_HT_DEBUG
283         printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
284 #endif
285         goto exit;
286
287 err_unlock_queue:
288         kfree(sta->ampdu_mlme.tid_tx[tid]);
289         sta->ampdu_mlme.tid_tx[tid] = NULL;
290         ret = -EBUSY;
291 err_unlock_sta:
292         spin_unlock_bh(&sta->lock);
293 exit:
294         rcu_read_unlock();
295         return ret;
296 }
297 EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
298
299 void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
300 {
301         struct ieee80211_local *local = hw_to_local(hw);
302         struct sta_info *sta;
303         u8 *state;
304
305         if (tid >= STA_TID_NUM) {
306 #ifdef CONFIG_MAC80211_HT_DEBUG
307                 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
308                                 tid, STA_TID_NUM);
309 #endif
310                 return;
311         }
312
313         rcu_read_lock();
314         sta = sta_info_get(local, ra);
315         if (!sta) {
316                 rcu_read_unlock();
317 #ifdef CONFIG_MAC80211_HT_DEBUG
318                 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
319 #endif
320                 return;
321         }
322
323         state = &sta->ampdu_mlme.tid_state_tx[tid];
324         spin_lock_bh(&sta->lock);
325
326         if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
327 #ifdef CONFIG_MAC80211_HT_DEBUG
328                 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
329                                 *state);
330 #endif
331                 spin_unlock_bh(&sta->lock);
332                 rcu_read_unlock();
333                 return;
334         }
335
336         WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
337
338         *state |= HT_ADDBA_DRV_READY_MSK;
339
340         if (*state == HT_AGG_STATE_OPERATIONAL) {
341 #ifdef CONFIG_MAC80211_HT_DEBUG
342                 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
343 #endif
344                 if (hw->ampdu_queues)
345                         ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
346         }
347         spin_unlock_bh(&sta->lock);
348         rcu_read_unlock();
349 }
350 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
351
352
353 int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
354                                  u8 *ra, u16 tid,
355                                  enum ieee80211_back_parties initiator)
356 {
357         struct ieee80211_local *local = hw_to_local(hw);
358         struct sta_info *sta;
359         u8 *state;
360         int ret = 0;
361
362         if (tid >= STA_TID_NUM)
363                 return -EINVAL;
364
365         rcu_read_lock();
366         sta = sta_info_get(local, ra);
367         if (!sta) {
368                 rcu_read_unlock();
369                 return -ENOENT;
370         }
371
372         /* check if the TID is in aggregation */
373         state = &sta->ampdu_mlme.tid_state_tx[tid];
374         spin_lock_bh(&sta->lock);
375
376         if (*state != HT_AGG_STATE_OPERATIONAL) {
377                 ret = -ENOENT;
378                 goto stop_BA_exit;
379         }
380
381 #ifdef CONFIG_MAC80211_HT_DEBUG
382         printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
383                ra, tid);
384 #endif /* CONFIG_MAC80211_HT_DEBUG */
385
386         if (hw->ampdu_queues)
387                 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
388
389         *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
390                 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
391
392         if (local->ops->ampdu_action)
393                 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
394                                                &sta->sta, tid, NULL);
395
396         /* case HW denied going back to legacy */
397         if (ret) {
398                 WARN_ON(ret != -EBUSY);
399                 *state = HT_AGG_STATE_OPERATIONAL;
400                 if (hw->ampdu_queues)
401                         ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
402                 goto stop_BA_exit;
403         }
404
405 stop_BA_exit:
406         spin_unlock_bh(&sta->lock);
407         rcu_read_unlock();
408         return ret;
409 }
410 EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
411
412 void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
413 {
414         struct ieee80211_local *local = hw_to_local(hw);
415         struct sta_info *sta;
416         u8 *state;
417         int agg_queue;
418
419         if (tid >= STA_TID_NUM) {
420 #ifdef CONFIG_MAC80211_HT_DEBUG
421                 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
422                                 tid, STA_TID_NUM);
423 #endif
424                 return;
425         }
426
427 #ifdef CONFIG_MAC80211_HT_DEBUG
428         printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
429                ra, tid);
430 #endif /* CONFIG_MAC80211_HT_DEBUG */
431
432         rcu_read_lock();
433         sta = sta_info_get(local, ra);
434         if (!sta) {
435 #ifdef CONFIG_MAC80211_HT_DEBUG
436                 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
437 #endif
438                 rcu_read_unlock();
439                 return;
440         }
441         state = &sta->ampdu_mlme.tid_state_tx[tid];
442
443         /* NOTE: no need to use sta->lock in this state check, as
444          * ieee80211_stop_tx_ba_session will let only one stop call to
445          * pass through per sta/tid
446          */
447         if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
448 #ifdef CONFIG_MAC80211_HT_DEBUG
449                 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
450 #endif
451                 rcu_read_unlock();
452                 return;
453         }
454
455         if (*state & HT_AGG_STATE_INITIATOR_MSK)
456                 ieee80211_send_delba(sta->sdata, ra, tid,
457                         WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
458
459         if (hw->ampdu_queues) {
460                 agg_queue = sta->tid_to_tx_q[tid];
461                 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
462
463                 /* We just requeued the all the frames that were in the
464                  * removed queue, and since we might miss a softirq we do
465                  * netif_schedule_queue.  ieee80211_wake_queue is not used
466                  * here as this queue is not necessarily stopped
467                  */
468                 netif_schedule_queue(netdev_get_tx_queue(local->mdev,
469                                                          agg_queue));
470         }
471         spin_lock_bh(&sta->lock);
472         *state = HT_AGG_STATE_IDLE;
473         sta->ampdu_mlme.addba_req_num[tid] = 0;
474         kfree(sta->ampdu_mlme.tid_tx[tid]);
475         sta->ampdu_mlme.tid_tx[tid] = NULL;
476         spin_unlock_bh(&sta->lock);
477
478         rcu_read_unlock();
479 }
480 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
481
482 void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
483                                       const u8 *ra, u16 tid)
484 {
485         struct ieee80211_local *local = hw_to_local(hw);
486         struct ieee80211_ra_tid *ra_tid;
487         struct sk_buff *skb = dev_alloc_skb(0);
488
489         if (unlikely(!skb)) {
490 #ifdef CONFIG_MAC80211_HT_DEBUG
491                 if (net_ratelimit())
492                         printk(KERN_WARNING "%s: Not enough memory, "
493                                "dropping start BA session", skb->dev->name);
494 #endif
495                 return;
496         }
497         ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
498         memcpy(&ra_tid->ra, ra, ETH_ALEN);
499         ra_tid->tid = tid;
500
501         skb->pkt_type = IEEE80211_ADDBA_MSG;
502         skb_queue_tail(&local->skb_queue, skb);
503         tasklet_schedule(&local->tasklet);
504 }
505 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
506
507 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
508                                      const u8 *ra, u16 tid)
509 {
510         struct ieee80211_local *local = hw_to_local(hw);
511         struct ieee80211_ra_tid *ra_tid;
512         struct sk_buff *skb = dev_alloc_skb(0);
513
514         if (unlikely(!skb)) {
515 #ifdef CONFIG_MAC80211_HT_DEBUG
516                 if (net_ratelimit())
517                         printk(KERN_WARNING "%s: Not enough memory, "
518                                "dropping stop BA session", skb->dev->name);
519 #endif
520                 return;
521         }
522         ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
523         memcpy(&ra_tid->ra, ra, ETH_ALEN);
524         ra_tid->tid = tid;
525
526         skb->pkt_type = IEEE80211_DELBA_MSG;
527         skb_queue_tail(&local->skb_queue, skb);
528         tasklet_schedule(&local->tasklet);
529 }
530 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
531
532 void ieee80211_process_addba_resp(struct ieee80211_local *local,
533                                   struct sta_info *sta,
534                                   struct ieee80211_mgmt *mgmt,
535                                   size_t len)
536 {
537         struct ieee80211_hw *hw = &local->hw;
538         u16 capab;
539         u16 tid, start_seq_num;
540         u8 *state;
541
542         capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
543         tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
544
545         state = &sta->ampdu_mlme.tid_state_tx[tid];
546
547         spin_lock_bh(&sta->lock);
548
549         if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
550                 spin_unlock_bh(&sta->lock);
551                 return;
552         }
553
554         if (mgmt->u.action.u.addba_resp.dialog_token !=
555                 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
556                 spin_unlock_bh(&sta->lock);
557 #ifdef CONFIG_MAC80211_HT_DEBUG
558                 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
559 #endif /* CONFIG_MAC80211_HT_DEBUG */
560                 return;
561         }
562
563         del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
564 #ifdef CONFIG_MAC80211_HT_DEBUG
565         printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
566 #endif /* CONFIG_MAC80211_HT_DEBUG */
567         if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
568                         == WLAN_STATUS_SUCCESS) {
569                 *state |= HT_ADDBA_RECEIVED_MSK;
570                 sta->ampdu_mlme.addba_req_num[tid] = 0;
571
572                 if (*state == HT_AGG_STATE_OPERATIONAL &&
573                     local->hw.ampdu_queues)
574                         ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
575
576                 if (local->ops->ampdu_action) {
577                         (void)local->ops->ampdu_action(hw,
578                                                IEEE80211_AMPDU_TX_RESUME,
579                                                &sta->sta, tid, &start_seq_num);
580                 }
581 #ifdef CONFIG_MAC80211_HT_DEBUG
582                 printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
583 #endif /* CONFIG_MAC80211_HT_DEBUG */
584                 spin_unlock_bh(&sta->lock);
585         } else {
586                 sta->ampdu_mlme.addba_req_num[tid]++;
587                 /* this will allow the state check in stop_BA_session */
588                 *state = HT_AGG_STATE_OPERATIONAL;
589                 spin_unlock_bh(&sta->lock);
590                 ieee80211_stop_tx_ba_session(hw, sta->sta.addr, tid,
591                                              WLAN_BACK_INITIATOR);
592         }
593 }