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-2008, Intel Corporation
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.
16 #include <linux/ieee80211.h>
17 #include <net/wireless.h>
18 #include <net/mac80211.h>
19 #include "ieee80211_i.h"
23 int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap
*ht_cap_ie
,
24 struct ieee80211_ht_info
*ht_info
)
30 memset(ht_info
, 0, sizeof(*ht_info
));
33 u8 ampdu_info
= ht_cap_ie
->ampdu_params_info
;
35 ht_info
->ht_supported
= 1;
36 ht_info
->cap
= le16_to_cpu(ht_cap_ie
->cap_info
);
37 ht_info
->ampdu_factor
=
38 ampdu_info
& IEEE80211_HT_CAP_AMPDU_FACTOR
;
39 ht_info
->ampdu_density
=
40 (ampdu_info
& IEEE80211_HT_CAP_AMPDU_DENSITY
) >> 2;
41 memcpy(ht_info
->supp_mcs_set
, ht_cap_ie
->supp_mcs_set
, 16);
43 ht_info
->ht_supported
= 0;
48 int ieee80211_ht_addt_info_ie_to_ht_bss_info(
49 struct ieee80211_ht_addt_info
*ht_add_info_ie
,
50 struct ieee80211_ht_bss_info
*bss_info
)
55 memset(bss_info
, 0, sizeof(*bss_info
));
59 op_mode
= le16_to_cpu(ht_add_info_ie
->operation_mode
);
61 bss_info
->primary_channel
= ht_add_info_ie
->control_chan
;
62 bss_info
->bss_cap
= ht_add_info_ie
->ht_param
;
63 bss_info
->bss_op_mode
= (u8
)(op_mode
& 0xff);
69 void ieee80211_send_addba_request(struct ieee80211_sub_if_data
*sdata
, const u8
*da
,
70 u16 tid
, u8 dialog_token
, u16 start_seq_num
,
71 u16 agg_size
, u16 timeout
)
73 struct ieee80211_local
*local
= sdata
->local
;
74 struct ieee80211_if_sta
*ifsta
= &sdata
->u
.sta
;
76 struct ieee80211_mgmt
*mgmt
;
79 skb
= dev_alloc_skb(sizeof(*mgmt
) + local
->hw
.extra_tx_headroom
);
82 printk(KERN_ERR
"%s: failed to allocate buffer "
83 "for addba request frame\n", sdata
->dev
->name
);
86 skb_reserve(skb
, local
->hw
.extra_tx_headroom
);
87 mgmt
= (struct ieee80211_mgmt
*) skb_put(skb
, 24);
89 memcpy(mgmt
->da
, da
, ETH_ALEN
);
90 memcpy(mgmt
->sa
, sdata
->dev
->dev_addr
, ETH_ALEN
);
91 if (sdata
->vif
.type
== IEEE80211_IF_TYPE_AP
)
92 memcpy(mgmt
->bssid
, sdata
->dev
->dev_addr
, ETH_ALEN
);
94 memcpy(mgmt
->bssid
, ifsta
->bssid
, ETH_ALEN
);
96 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
97 IEEE80211_STYPE_ACTION
);
99 skb_put(skb
, 1 + sizeof(mgmt
->u
.action
.u
.addba_req
));
101 mgmt
->u
.action
.category
= WLAN_CATEGORY_BACK
;
102 mgmt
->u
.action
.u
.addba_req
.action_code
= WLAN_ACTION_ADDBA_REQ
;
104 mgmt
->u
.action
.u
.addba_req
.dialog_token
= dialog_token
;
105 capab
= (u16
)(1 << 1); /* bit 1 aggregation policy */
106 capab
|= (u16
)(tid
<< 2); /* bit 5:2 TID number */
107 capab
|= (u16
)(agg_size
<< 6); /* bit 15:6 max size of aggergation */
109 mgmt
->u
.action
.u
.addba_req
.capab
= cpu_to_le16(capab
);
111 mgmt
->u
.action
.u
.addba_req
.timeout
= cpu_to_le16(timeout
);
112 mgmt
->u
.action
.u
.addba_req
.start_seq_num
=
113 cpu_to_le16(start_seq_num
<< 4);
115 ieee80211_sta_tx(sdata
, skb
, 0);
118 void ieee80211_send_delba(struct ieee80211_sub_if_data
*sdata
, const u8
*da
, u16 tid
,
119 u16 initiator
, u16 reason_code
)
121 struct ieee80211_local
*local
= sdata
->local
;
122 struct ieee80211_if_sta
*ifsta
= &sdata
->u
.sta
;
124 struct ieee80211_mgmt
*mgmt
;
127 skb
= dev_alloc_skb(sizeof(*mgmt
) + local
->hw
.extra_tx_headroom
);
130 printk(KERN_ERR
"%s: failed to allocate buffer "
131 "for delba frame\n", sdata
->dev
->name
);
135 skb_reserve(skb
, local
->hw
.extra_tx_headroom
);
136 mgmt
= (struct ieee80211_mgmt
*) skb_put(skb
, 24);
138 memcpy(mgmt
->da
, da
, ETH_ALEN
);
139 memcpy(mgmt
->sa
, sdata
->dev
->dev_addr
, ETH_ALEN
);
140 if (sdata
->vif
.type
== IEEE80211_IF_TYPE_AP
)
141 memcpy(mgmt
->bssid
, sdata
->dev
->dev_addr
, ETH_ALEN
);
143 memcpy(mgmt
->bssid
, ifsta
->bssid
, ETH_ALEN
);
144 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
145 IEEE80211_STYPE_ACTION
);
147 skb_put(skb
, 1 + sizeof(mgmt
->u
.action
.u
.delba
));
149 mgmt
->u
.action
.category
= WLAN_CATEGORY_BACK
;
150 mgmt
->u
.action
.u
.delba
.action_code
= WLAN_ACTION_DELBA
;
151 params
= (u16
)(initiator
<< 11); /* bit 11 initiator */
152 params
|= (u16
)(tid
<< 12); /* bit 15:12 TID number */
154 mgmt
->u
.action
.u
.delba
.params
= cpu_to_le16(params
);
155 mgmt
->u
.action
.u
.delba
.reason_code
= cpu_to_le16(reason_code
);
157 ieee80211_sta_tx(sdata
, skb
, 0);
160 void ieee80211_send_bar(struct ieee80211_sub_if_data
*sdata
, u8
*ra
, u16 tid
, u16 ssn
)
162 struct ieee80211_local
*local
= sdata
->local
;
164 struct ieee80211_bar
*bar
;
167 skb
= dev_alloc_skb(sizeof(*bar
) + local
->hw
.extra_tx_headroom
);
169 printk(KERN_ERR
"%s: failed to allocate buffer for "
170 "bar frame\n", sdata
->dev
->name
);
173 skb_reserve(skb
, local
->hw
.extra_tx_headroom
);
174 bar
= (struct ieee80211_bar
*)skb_put(skb
, sizeof(*bar
));
175 memset(bar
, 0, sizeof(*bar
));
176 bar
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_CTL
|
177 IEEE80211_STYPE_BACK_REQ
);
178 memcpy(bar
->ra
, ra
, ETH_ALEN
);
179 memcpy(bar
->ta
, sdata
->dev
->dev_addr
, ETH_ALEN
);
180 bar_control
|= (u16
)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL
;
181 bar_control
|= (u16
)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA
;
182 bar_control
|= (u16
)(tid
<< 12);
183 bar
->control
= cpu_to_le16(bar_control
);
184 bar
->start_seq_num
= cpu_to_le16(ssn
);
186 ieee80211_sta_tx(sdata
, skb
, 0);
189 void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data
*sdata
, u8
*ra
, u16 tid
,
190 u16 initiator
, u16 reason
)
192 struct ieee80211_local
*local
= sdata
->local
;
193 struct ieee80211_hw
*hw
= &local
->hw
;
194 struct sta_info
*sta
;
196 DECLARE_MAC_BUF(mac
);
200 sta
= sta_info_get(local
, ra
);
206 /* check if TID is in operational state */
207 spin_lock_bh(&sta
->lock
);
208 if (sta
->ampdu_mlme
.tid_state_rx
[tid
]
209 != HT_AGG_STATE_OPERATIONAL
) {
210 spin_unlock_bh(&sta
->lock
);
214 sta
->ampdu_mlme
.tid_state_rx
[tid
] =
215 HT_AGG_STATE_REQ_STOP_BA_MSK
|
216 (initiator
<< HT_AGG_STATE_INITIATOR_SHIFT
);
217 spin_unlock_bh(&sta
->lock
);
219 /* stop HW Rx aggregation. ampdu_action existence
220 * already verified in session init so we add the BUG_ON */
221 BUG_ON(!local
->ops
->ampdu_action
);
223 #ifdef CONFIG_MAC80211_HT_DEBUG
224 printk(KERN_DEBUG
"Rx BA session stop requested for %s tid %u\n",
225 print_mac(mac
, ra
), tid
);
226 #endif /* CONFIG_MAC80211_HT_DEBUG */
228 ret
= local
->ops
->ampdu_action(hw
, IEEE80211_AMPDU_RX_STOP
,
231 printk(KERN_DEBUG
"HW problem - can not stop rx "
232 "aggregation for tid %d\n", tid
);
234 /* shutdown timer has not expired */
235 if (initiator
!= WLAN_BACK_TIMER
)
236 del_timer_sync(&sta
->ampdu_mlme
.tid_rx
[tid
]->session_timer
);
238 /* check if this is a self generated aggregation halt */
239 if (initiator
== WLAN_BACK_RECIPIENT
|| initiator
== WLAN_BACK_TIMER
)
240 ieee80211_send_delba(sdata
, ra
, tid
, 0, reason
);
242 /* free the reordering buffer */
243 for (i
= 0; i
< sta
->ampdu_mlme
.tid_rx
[tid
]->buf_size
; i
++) {
244 if (sta
->ampdu_mlme
.tid_rx
[tid
]->reorder_buf
[i
]) {
245 /* release the reordered frames */
246 dev_kfree_skb(sta
->ampdu_mlme
.tid_rx
[tid
]->reorder_buf
[i
]);
247 sta
->ampdu_mlme
.tid_rx
[tid
]->stored_mpdu_num
--;
248 sta
->ampdu_mlme
.tid_rx
[tid
]->reorder_buf
[i
] = NULL
;
252 kfree(sta
->ampdu_mlme
.tid_rx
[tid
]->reorder_buf
);
253 kfree(sta
->ampdu_mlme
.tid_rx
[tid
]);
254 sta
->ampdu_mlme
.tid_rx
[tid
] = NULL
;
255 sta
->ampdu_mlme
.tid_state_rx
[tid
] = HT_AGG_STATE_IDLE
;
262 * After sending add Block Ack request we activated a timer until
263 * add Block Ack response will arrive from the recipient.
264 * If this timer expires sta_addba_resp_timer_expired will be executed.
266 void sta_addba_resp_timer_expired(unsigned long data
)
268 /* not an elegant detour, but there is no choice as the timer passes
269 * only one argument, and both sta_info and TID are needed, so init
270 * flow in sta_info_create gives the TID as data, while the timer_to_id
271 * array gives the sta through container_of */
272 u16 tid
= *(u8
*)data
;
273 struct sta_info
*temp_sta
= container_of((void *)data
,
274 struct sta_info
, timer_to_tid
[tid
]);
276 struct ieee80211_local
*local
= temp_sta
->local
;
277 struct ieee80211_hw
*hw
= &local
->hw
;
278 struct sta_info
*sta
;
283 sta
= sta_info_get(local
, temp_sta
->addr
);
289 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
290 /* check if the TID waits for addBA response */
291 spin_lock_bh(&sta
->lock
);
292 if (!(*state
& HT_ADDBA_REQUESTED_MSK
)) {
293 spin_unlock_bh(&sta
->lock
);
294 *state
= HT_AGG_STATE_IDLE
;
295 #ifdef CONFIG_MAC80211_HT_DEBUG
296 printk(KERN_DEBUG
"timer expired on tid %d but we are not "
297 "expecting addBA response there", tid
);
299 goto timer_expired_exit
;
302 #ifdef CONFIG_MAC80211_HT_DEBUG
303 printk(KERN_DEBUG
"addBA response timer expired on tid %d\n", tid
);
306 /* go through the state check in stop_BA_session */
307 *state
= HT_AGG_STATE_OPERATIONAL
;
308 spin_unlock_bh(&sta
->lock
);
309 ieee80211_stop_tx_ba_session(hw
, temp_sta
->addr
, tid
,
310 WLAN_BACK_INITIATOR
);
316 void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data
*sdata
, u8
*addr
)
318 struct ieee80211_local
*local
= sdata
->local
;
321 for (i
= 0; i
< STA_TID_NUM
; i
++) {
322 ieee80211_stop_tx_ba_session(&local
->hw
, addr
, i
,
323 WLAN_BACK_INITIATOR
);
324 ieee80211_sta_stop_rx_ba_session(sdata
, addr
, i
,
326 WLAN_REASON_QSTA_LEAVE_QBSS
);
330 int ieee80211_start_tx_ba_session(struct ieee80211_hw
*hw
, u8
*ra
, u16 tid
)
332 struct ieee80211_local
*local
= hw_to_local(hw
);
333 struct sta_info
*sta
;
334 struct ieee80211_sub_if_data
*sdata
;
338 DECLARE_MAC_BUF(mac
);
340 if (tid
>= STA_TID_NUM
)
343 #ifdef CONFIG_MAC80211_HT_DEBUG
344 printk(KERN_DEBUG
"Open BA session requested for %s tid %u\n",
345 print_mac(mac
, ra
), tid
);
346 #endif /* CONFIG_MAC80211_HT_DEBUG */
350 sta
= sta_info_get(local
, ra
);
352 #ifdef CONFIG_MAC80211_HT_DEBUG
353 printk(KERN_DEBUG
"Could not find the station\n");
359 spin_lock_bh(&sta
->lock
);
361 /* we have tried too many times, receiver does not want A-MPDU */
362 if (sta
->ampdu_mlme
.addba_req_num
[tid
] > HT_AGG_MAX_RETRIES
) {
367 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
368 /* check if the TID is not in aggregation flow already */
369 if (*state
!= HT_AGG_STATE_IDLE
) {
370 #ifdef CONFIG_MAC80211_HT_DEBUG
371 printk(KERN_DEBUG
"BA request denied - session is not "
372 "idle on tid %u\n", tid
);
373 #endif /* CONFIG_MAC80211_HT_DEBUG */
378 /* prepare A-MPDU MLME for Tx aggregation */
379 sta
->ampdu_mlme
.tid_tx
[tid
] =
380 kmalloc(sizeof(struct tid_ampdu_tx
), GFP_ATOMIC
);
381 if (!sta
->ampdu_mlme
.tid_tx
[tid
]) {
382 #ifdef CONFIG_MAC80211_HT_DEBUG
384 printk(KERN_ERR
"allocate tx mlme to tid %d failed\n",
391 sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
.function
=
392 sta_addba_resp_timer_expired
;
393 sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
.data
=
394 (unsigned long)&sta
->timer_to_tid
[tid
];
395 init_timer(&sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
);
397 /* create a new queue for this aggregation */
398 ret
= ieee80211_ht_agg_queue_add(local
, sta
, tid
);
400 /* case no queue is available to aggregation
401 * don't switch to aggregation */
403 #ifdef CONFIG_MAC80211_HT_DEBUG
404 printk(KERN_DEBUG
"BA request denied - queue unavailable for"
406 #endif /* CONFIG_MAC80211_HT_DEBUG */
407 goto err_unlock_queue
;
411 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
412 * call back right away, it must see that the flow has begun */
413 *state
|= HT_ADDBA_REQUESTED_MSK
;
415 /* This is slightly racy because the queue isn't stopped */
416 start_seq_num
= sta
->tid_seq
[tid
];
418 if (local
->ops
->ampdu_action
)
419 ret
= local
->ops
->ampdu_action(hw
, IEEE80211_AMPDU_TX_START
,
420 ra
, tid
, &start_seq_num
);
423 /* No need to requeue the packets in the agg queue, since we
424 * held the tx lock: no packet could be enqueued to the newly
426 ieee80211_ht_agg_queue_remove(local
, sta
, tid
, 0);
427 #ifdef CONFIG_MAC80211_HT_DEBUG
428 printk(KERN_DEBUG
"BA request denied - HW unavailable for"
430 #endif /* CONFIG_MAC80211_HT_DEBUG */
431 *state
= HT_AGG_STATE_IDLE
;
432 goto err_unlock_queue
;
435 /* Will put all the packets in the new SW queue */
436 ieee80211_requeue(local
, ieee802_1d_to_ac
[tid
]);
437 spin_unlock_bh(&sta
->lock
);
439 /* send an addBA request */
440 sta
->ampdu_mlme
.dialog_token_allocator
++;
441 sta
->ampdu_mlme
.tid_tx
[tid
]->dialog_token
=
442 sta
->ampdu_mlme
.dialog_token_allocator
;
443 sta
->ampdu_mlme
.tid_tx
[tid
]->ssn
= start_seq_num
;
446 ieee80211_send_addba_request(sta
->sdata
, ra
, tid
,
447 sta
->ampdu_mlme
.tid_tx
[tid
]->dialog_token
,
448 sta
->ampdu_mlme
.tid_tx
[tid
]->ssn
,
450 /* activate the timer for the recipient's addBA response */
451 sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
.expires
=
452 jiffies
+ ADDBA_RESP_INTERVAL
;
453 add_timer(&sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
);
454 #ifdef CONFIG_MAC80211_HT_DEBUG
455 printk(KERN_DEBUG
"activated addBA response timer on tid %d\n", tid
);
460 kfree(sta
->ampdu_mlme
.tid_tx
[tid
]);
461 sta
->ampdu_mlme
.tid_tx
[tid
] = NULL
;
464 spin_unlock_bh(&sta
->lock
);
469 EXPORT_SYMBOL(ieee80211_start_tx_ba_session
);
471 int ieee80211_stop_tx_ba_session(struct ieee80211_hw
*hw
,
473 enum ieee80211_back_parties initiator
)
475 struct ieee80211_local
*local
= hw_to_local(hw
);
476 struct sta_info
*sta
;
479 DECLARE_MAC_BUF(mac
);
481 if (tid
>= STA_TID_NUM
)
485 sta
= sta_info_get(local
, ra
);
491 /* check if the TID is in aggregation */
492 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
493 spin_lock_bh(&sta
->lock
);
495 if (*state
!= HT_AGG_STATE_OPERATIONAL
) {
500 #ifdef CONFIG_MAC80211_HT_DEBUG
501 printk(KERN_DEBUG
"Tx BA session stop requested for %s tid %u\n",
502 print_mac(mac
, ra
), tid
);
503 #endif /* CONFIG_MAC80211_HT_DEBUG */
505 ieee80211_stop_queue(hw
, sta
->tid_to_tx_q
[tid
]);
507 *state
= HT_AGG_STATE_REQ_STOP_BA_MSK
|
508 (initiator
<< HT_AGG_STATE_INITIATOR_SHIFT
);
510 if (local
->ops
->ampdu_action
)
511 ret
= local
->ops
->ampdu_action(hw
, IEEE80211_AMPDU_TX_STOP
,
514 /* case HW denied going back to legacy */
516 WARN_ON(ret
!= -EBUSY
);
517 *state
= HT_AGG_STATE_OPERATIONAL
;
518 ieee80211_wake_queue(hw
, sta
->tid_to_tx_q
[tid
]);
523 spin_unlock_bh(&sta
->lock
);
527 EXPORT_SYMBOL(ieee80211_stop_tx_ba_session
);
529 void ieee80211_start_tx_ba_cb(struct ieee80211_hw
*hw
, u8
*ra
, u16 tid
)
531 struct ieee80211_local
*local
= hw_to_local(hw
);
532 struct sta_info
*sta
;
534 DECLARE_MAC_BUF(mac
);
536 if (tid
>= STA_TID_NUM
) {
537 #ifdef CONFIG_MAC80211_HT_DEBUG
538 printk(KERN_DEBUG
"Bad TID value: tid = %d (>= %d)\n",
545 sta
= sta_info_get(local
, ra
);
548 #ifdef CONFIG_MAC80211_HT_DEBUG
549 printk(KERN_DEBUG
"Could not find station: %s\n",
555 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
556 spin_lock_bh(&sta
->lock
);
558 if (!(*state
& HT_ADDBA_REQUESTED_MSK
)) {
559 #ifdef CONFIG_MAC80211_HT_DEBUG
560 printk(KERN_DEBUG
"addBA was not requested yet, state is %d\n",
563 spin_unlock_bh(&sta
->lock
);
568 WARN_ON_ONCE(*state
& HT_ADDBA_DRV_READY_MSK
);
570 *state
|= HT_ADDBA_DRV_READY_MSK
;
572 if (*state
== HT_AGG_STATE_OPERATIONAL
) {
573 #ifdef CONFIG_MAC80211_HT_DEBUG
574 printk(KERN_DEBUG
"Aggregation is on for tid %d \n", tid
);
576 ieee80211_wake_queue(hw
, sta
->tid_to_tx_q
[tid
]);
578 spin_unlock_bh(&sta
->lock
);
581 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb
);
583 void ieee80211_stop_tx_ba_cb(struct ieee80211_hw
*hw
, u8
*ra
, u8 tid
)
585 struct ieee80211_local
*local
= hw_to_local(hw
);
586 struct sta_info
*sta
;
589 DECLARE_MAC_BUF(mac
);
591 if (tid
>= STA_TID_NUM
) {
592 #ifdef CONFIG_MAC80211_HT_DEBUG
593 printk(KERN_DEBUG
"Bad TID value: tid = %d (>= %d)\n",
599 #ifdef CONFIG_MAC80211_HT_DEBUG
600 printk(KERN_DEBUG
"Stopping Tx BA session for %s tid %d\n",
601 print_mac(mac
, ra
), tid
);
602 #endif /* CONFIG_MAC80211_HT_DEBUG */
605 sta
= sta_info_get(local
, ra
);
607 #ifdef CONFIG_MAC80211_HT_DEBUG
608 printk(KERN_DEBUG
"Could not find station: %s\n",
614 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
616 /* NOTE: no need to use sta->lock in this state check, as
617 * ieee80211_stop_tx_ba_session will let only one stop call to
618 * pass through per sta/tid
620 if ((*state
& HT_AGG_STATE_REQ_STOP_BA_MSK
) == 0) {
621 #ifdef CONFIG_MAC80211_HT_DEBUG
622 printk(KERN_DEBUG
"unexpected callback to A-MPDU stop\n");
628 if (*state
& HT_AGG_STATE_INITIATOR_MSK
)
629 ieee80211_send_delba(sta
->sdata
, ra
, tid
,
630 WLAN_BACK_INITIATOR
, WLAN_REASON_QSTA_NOT_USE
);
632 agg_queue
= sta
->tid_to_tx_q
[tid
];
634 ieee80211_ht_agg_queue_remove(local
, sta
, tid
, 1);
636 /* We just requeued the all the frames that were in the
637 * removed queue, and since we might miss a softirq we do
638 * netif_schedule_queue. ieee80211_wake_queue is not used
639 * here as this queue is not necessarily stopped
641 netif_schedule_queue(netdev_get_tx_queue(local
->mdev
, agg_queue
));
642 spin_lock_bh(&sta
->lock
);
643 *state
= HT_AGG_STATE_IDLE
;
644 sta
->ampdu_mlme
.addba_req_num
[tid
] = 0;
645 kfree(sta
->ampdu_mlme
.tid_tx
[tid
]);
646 sta
->ampdu_mlme
.tid_tx
[tid
] = NULL
;
647 spin_unlock_bh(&sta
->lock
);
651 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb
);
653 void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw
*hw
,
654 const u8
*ra
, u16 tid
)
656 struct ieee80211_local
*local
= hw_to_local(hw
);
657 struct ieee80211_ra_tid
*ra_tid
;
658 struct sk_buff
*skb
= dev_alloc_skb(0);
660 if (unlikely(!skb
)) {
661 #ifdef CONFIG_MAC80211_HT_DEBUG
663 printk(KERN_WARNING
"%s: Not enough memory, "
664 "dropping start BA session", skb
->dev
->name
);
668 ra_tid
= (struct ieee80211_ra_tid
*) &skb
->cb
;
669 memcpy(&ra_tid
->ra
, ra
, ETH_ALEN
);
672 skb
->pkt_type
= IEEE80211_ADDBA_MSG
;
673 skb_queue_tail(&local
->skb_queue
, skb
);
674 tasklet_schedule(&local
->tasklet
);
676 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe
);
678 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw
*hw
,
679 const u8
*ra
, u16 tid
)
681 struct ieee80211_local
*local
= hw_to_local(hw
);
682 struct ieee80211_ra_tid
*ra_tid
;
683 struct sk_buff
*skb
= dev_alloc_skb(0);
685 if (unlikely(!skb
)) {
686 #ifdef CONFIG_MAC80211_HT_DEBUG
688 printk(KERN_WARNING
"%s: Not enough memory, "
689 "dropping stop BA session", skb
->dev
->name
);
693 ra_tid
= (struct ieee80211_ra_tid
*) &skb
->cb
;
694 memcpy(&ra_tid
->ra
, ra
, ETH_ALEN
);
697 skb
->pkt_type
= IEEE80211_DELBA_MSG
;
698 skb_queue_tail(&local
->skb_queue
, skb
);
699 tasklet_schedule(&local
->tasklet
);
701 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe
);