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 static void ieee80211_send_addba_request(struct ieee80211_sub_if_data
*sdata
,
70 const u8
*da
, u16 tid
,
71 u8 dialog_token
, u16 start_seq_num
,
72 u16 agg_size
, u16 timeout
)
74 struct ieee80211_local
*local
= sdata
->local
;
75 struct ieee80211_if_sta
*ifsta
= &sdata
->u
.sta
;
77 struct ieee80211_mgmt
*mgmt
;
80 skb
= dev_alloc_skb(sizeof(*mgmt
) + local
->hw
.extra_tx_headroom
);
83 printk(KERN_ERR
"%s: failed to allocate buffer "
84 "for addba request frame\n", sdata
->dev
->name
);
87 skb_reserve(skb
, local
->hw
.extra_tx_headroom
);
88 mgmt
= (struct ieee80211_mgmt
*) skb_put(skb
, 24);
90 memcpy(mgmt
->da
, da
, ETH_ALEN
);
91 memcpy(mgmt
->sa
, sdata
->dev
->dev_addr
, ETH_ALEN
);
92 if (sdata
->vif
.type
== NL80211_IFTYPE_AP
)
93 memcpy(mgmt
->bssid
, sdata
->dev
->dev_addr
, ETH_ALEN
);
95 memcpy(mgmt
->bssid
, ifsta
->bssid
, ETH_ALEN
);
97 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
98 IEEE80211_STYPE_ACTION
);
100 skb_put(skb
, 1 + sizeof(mgmt
->u
.action
.u
.addba_req
));
102 mgmt
->u
.action
.category
= WLAN_CATEGORY_BACK
;
103 mgmt
->u
.action
.u
.addba_req
.action_code
= WLAN_ACTION_ADDBA_REQ
;
105 mgmt
->u
.action
.u
.addba_req
.dialog_token
= dialog_token
;
106 capab
= (u16
)(1 << 1); /* bit 1 aggregation policy */
107 capab
|= (u16
)(tid
<< 2); /* bit 5:2 TID number */
108 capab
|= (u16
)(agg_size
<< 6); /* bit 15:6 max size of aggergation */
110 mgmt
->u
.action
.u
.addba_req
.capab
= cpu_to_le16(capab
);
112 mgmt
->u
.action
.u
.addba_req
.timeout
= cpu_to_le16(timeout
);
113 mgmt
->u
.action
.u
.addba_req
.start_seq_num
=
114 cpu_to_le16(start_seq_num
<< 4);
116 ieee80211_tx_skb(sdata
, skb
, 0);
119 static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data
*sdata
, u8
*da
, u16 tid
,
120 u8 dialog_token
, u16 status
, u16 policy
,
121 u16 buf_size
, u16 timeout
)
123 struct ieee80211_if_sta
*ifsta
= &sdata
->u
.sta
;
124 struct ieee80211_local
*local
= sdata
->local
;
126 struct ieee80211_mgmt
*mgmt
;
129 skb
= dev_alloc_skb(sizeof(*mgmt
) + local
->hw
.extra_tx_headroom
);
132 printk(KERN_DEBUG
"%s: failed to allocate buffer "
133 "for addba resp frame\n", sdata
->dev
->name
);
137 skb_reserve(skb
, local
->hw
.extra_tx_headroom
);
138 mgmt
= (struct ieee80211_mgmt
*) skb_put(skb
, 24);
140 memcpy(mgmt
->da
, da
, ETH_ALEN
);
141 memcpy(mgmt
->sa
, sdata
->dev
->dev_addr
, ETH_ALEN
);
142 if (sdata
->vif
.type
== NL80211_IFTYPE_AP
)
143 memcpy(mgmt
->bssid
, sdata
->dev
->dev_addr
, ETH_ALEN
);
145 memcpy(mgmt
->bssid
, ifsta
->bssid
, ETH_ALEN
);
146 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
147 IEEE80211_STYPE_ACTION
);
149 skb_put(skb
, 1 + sizeof(mgmt
->u
.action
.u
.addba_resp
));
150 mgmt
->u
.action
.category
= WLAN_CATEGORY_BACK
;
151 mgmt
->u
.action
.u
.addba_resp
.action_code
= WLAN_ACTION_ADDBA_RESP
;
152 mgmt
->u
.action
.u
.addba_resp
.dialog_token
= dialog_token
;
154 capab
= (u16
)(policy
<< 1); /* bit 1 aggregation policy */
155 capab
|= (u16
)(tid
<< 2); /* bit 5:2 TID number */
156 capab
|= (u16
)(buf_size
<< 6); /* bit 15:6 max size of aggregation */
158 mgmt
->u
.action
.u
.addba_resp
.capab
= cpu_to_le16(capab
);
159 mgmt
->u
.action
.u
.addba_resp
.timeout
= cpu_to_le16(timeout
);
160 mgmt
->u
.action
.u
.addba_resp
.status
= cpu_to_le16(status
);
162 ieee80211_tx_skb(sdata
, skb
, 0);
165 static void ieee80211_send_delba(struct ieee80211_sub_if_data
*sdata
,
166 const u8
*da
, u16 tid
,
167 u16 initiator
, u16 reason_code
)
169 struct ieee80211_local
*local
= sdata
->local
;
170 struct ieee80211_if_sta
*ifsta
= &sdata
->u
.sta
;
172 struct ieee80211_mgmt
*mgmt
;
175 skb
= dev_alloc_skb(sizeof(*mgmt
) + local
->hw
.extra_tx_headroom
);
178 printk(KERN_ERR
"%s: failed to allocate buffer "
179 "for delba frame\n", sdata
->dev
->name
);
183 skb_reserve(skb
, local
->hw
.extra_tx_headroom
);
184 mgmt
= (struct ieee80211_mgmt
*) skb_put(skb
, 24);
186 memcpy(mgmt
->da
, da
, ETH_ALEN
);
187 memcpy(mgmt
->sa
, sdata
->dev
->dev_addr
, ETH_ALEN
);
188 if (sdata
->vif
.type
== NL80211_IFTYPE_AP
)
189 memcpy(mgmt
->bssid
, sdata
->dev
->dev_addr
, ETH_ALEN
);
191 memcpy(mgmt
->bssid
, ifsta
->bssid
, ETH_ALEN
);
192 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
193 IEEE80211_STYPE_ACTION
);
195 skb_put(skb
, 1 + sizeof(mgmt
->u
.action
.u
.delba
));
197 mgmt
->u
.action
.category
= WLAN_CATEGORY_BACK
;
198 mgmt
->u
.action
.u
.delba
.action_code
= WLAN_ACTION_DELBA
;
199 params
= (u16
)(initiator
<< 11); /* bit 11 initiator */
200 params
|= (u16
)(tid
<< 12); /* bit 15:12 TID number */
202 mgmt
->u
.action
.u
.delba
.params
= cpu_to_le16(params
);
203 mgmt
->u
.action
.u
.delba
.reason_code
= cpu_to_le16(reason_code
);
205 ieee80211_tx_skb(sdata
, skb
, 0);
208 void ieee80211_send_bar(struct ieee80211_sub_if_data
*sdata
, u8
*ra
, u16 tid
, u16 ssn
)
210 struct ieee80211_local
*local
= sdata
->local
;
212 struct ieee80211_bar
*bar
;
215 skb
= dev_alloc_skb(sizeof(*bar
) + local
->hw
.extra_tx_headroom
);
217 printk(KERN_ERR
"%s: failed to allocate buffer for "
218 "bar frame\n", sdata
->dev
->name
);
221 skb_reserve(skb
, local
->hw
.extra_tx_headroom
);
222 bar
= (struct ieee80211_bar
*)skb_put(skb
, sizeof(*bar
));
223 memset(bar
, 0, sizeof(*bar
));
224 bar
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_CTL
|
225 IEEE80211_STYPE_BACK_REQ
);
226 memcpy(bar
->ra
, ra
, ETH_ALEN
);
227 memcpy(bar
->ta
, sdata
->dev
->dev_addr
, ETH_ALEN
);
228 bar_control
|= (u16
)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL
;
229 bar_control
|= (u16
)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA
;
230 bar_control
|= (u16
)(tid
<< 12);
231 bar
->control
= cpu_to_le16(bar_control
);
232 bar
->start_seq_num
= cpu_to_le16(ssn
);
234 ieee80211_tx_skb(sdata
, skb
, 0);
237 void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data
*sdata
, u8
*ra
, u16 tid
,
238 u16 initiator
, u16 reason
)
240 struct ieee80211_local
*local
= sdata
->local
;
241 struct ieee80211_hw
*hw
= &local
->hw
;
242 struct sta_info
*sta
;
244 DECLARE_MAC_BUF(mac
);
248 sta
= sta_info_get(local
, ra
);
254 /* check if TID is in operational state */
255 spin_lock_bh(&sta
->lock
);
256 if (sta
->ampdu_mlme
.tid_state_rx
[tid
]
257 != HT_AGG_STATE_OPERATIONAL
) {
258 spin_unlock_bh(&sta
->lock
);
262 sta
->ampdu_mlme
.tid_state_rx
[tid
] =
263 HT_AGG_STATE_REQ_STOP_BA_MSK
|
264 (initiator
<< HT_AGG_STATE_INITIATOR_SHIFT
);
265 spin_unlock_bh(&sta
->lock
);
267 /* stop HW Rx aggregation. ampdu_action existence
268 * already verified in session init so we add the BUG_ON */
269 BUG_ON(!local
->ops
->ampdu_action
);
271 #ifdef CONFIG_MAC80211_HT_DEBUG
272 printk(KERN_DEBUG
"Rx BA session stop requested for %s tid %u\n",
273 print_mac(mac
, ra
), tid
);
274 #endif /* CONFIG_MAC80211_HT_DEBUG */
276 ret
= local
->ops
->ampdu_action(hw
, IEEE80211_AMPDU_RX_STOP
,
277 &sta
->sta
, tid
, NULL
);
279 printk(KERN_DEBUG
"HW problem - can not stop rx "
280 "aggregation for tid %d\n", tid
);
282 /* shutdown timer has not expired */
283 if (initiator
!= WLAN_BACK_TIMER
)
284 del_timer_sync(&sta
->ampdu_mlme
.tid_rx
[tid
]->session_timer
);
286 /* check if this is a self generated aggregation halt */
287 if (initiator
== WLAN_BACK_RECIPIENT
|| initiator
== WLAN_BACK_TIMER
)
288 ieee80211_send_delba(sdata
, ra
, tid
, 0, reason
);
290 /* free the reordering buffer */
291 for (i
= 0; i
< sta
->ampdu_mlme
.tid_rx
[tid
]->buf_size
; i
++) {
292 if (sta
->ampdu_mlme
.tid_rx
[tid
]->reorder_buf
[i
]) {
293 /* release the reordered frames */
294 dev_kfree_skb(sta
->ampdu_mlme
.tid_rx
[tid
]->reorder_buf
[i
]);
295 sta
->ampdu_mlme
.tid_rx
[tid
]->stored_mpdu_num
--;
296 sta
->ampdu_mlme
.tid_rx
[tid
]->reorder_buf
[i
] = NULL
;
300 kfree(sta
->ampdu_mlme
.tid_rx
[tid
]->reorder_buf
);
301 kfree(sta
->ampdu_mlme
.tid_rx
[tid
]);
302 sta
->ampdu_mlme
.tid_rx
[tid
] = NULL
;
303 sta
->ampdu_mlme
.tid_state_rx
[tid
] = HT_AGG_STATE_IDLE
;
310 * After sending add Block Ack request we activated a timer until
311 * add Block Ack response will arrive from the recipient.
312 * If this timer expires sta_addba_resp_timer_expired will be executed.
314 static void sta_addba_resp_timer_expired(unsigned long data
)
316 /* not an elegant detour, but there is no choice as the timer passes
317 * only one argument, and both sta_info and TID are needed, so init
318 * flow in sta_info_create gives the TID as data, while the timer_to_id
319 * array gives the sta through container_of */
320 u16 tid
= *(u8
*)data
;
321 struct sta_info
*temp_sta
= container_of((void *)data
,
322 struct sta_info
, timer_to_tid
[tid
]);
324 struct ieee80211_local
*local
= temp_sta
->local
;
325 struct ieee80211_hw
*hw
= &local
->hw
;
326 struct sta_info
*sta
;
331 sta
= sta_info_get(local
, temp_sta
->sta
.addr
);
337 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
338 /* check if the TID waits for addBA response */
339 spin_lock_bh(&sta
->lock
);
340 if (!(*state
& HT_ADDBA_REQUESTED_MSK
)) {
341 spin_unlock_bh(&sta
->lock
);
342 *state
= HT_AGG_STATE_IDLE
;
343 #ifdef CONFIG_MAC80211_HT_DEBUG
344 printk(KERN_DEBUG
"timer expired on tid %d but we are not "
345 "expecting addBA response there", tid
);
347 goto timer_expired_exit
;
350 #ifdef CONFIG_MAC80211_HT_DEBUG
351 printk(KERN_DEBUG
"addBA response timer expired on tid %d\n", tid
);
354 /* go through the state check in stop_BA_session */
355 *state
= HT_AGG_STATE_OPERATIONAL
;
356 spin_unlock_bh(&sta
->lock
);
357 ieee80211_stop_tx_ba_session(hw
, temp_sta
->sta
.addr
, tid
,
358 WLAN_BACK_INITIATOR
);
364 void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data
*sdata
, u8
*addr
)
366 struct ieee80211_local
*local
= sdata
->local
;
369 for (i
= 0; i
< STA_TID_NUM
; i
++) {
370 ieee80211_stop_tx_ba_session(&local
->hw
, addr
, i
,
371 WLAN_BACK_INITIATOR
);
372 ieee80211_sta_stop_rx_ba_session(sdata
, addr
, i
,
374 WLAN_REASON_QSTA_LEAVE_QBSS
);
378 int ieee80211_start_tx_ba_session(struct ieee80211_hw
*hw
, u8
*ra
, u16 tid
)
380 struct ieee80211_local
*local
= hw_to_local(hw
);
381 struct sta_info
*sta
;
382 struct ieee80211_sub_if_data
*sdata
;
386 DECLARE_MAC_BUF(mac
);
388 if (tid
>= STA_TID_NUM
)
391 #ifdef CONFIG_MAC80211_HT_DEBUG
392 printk(KERN_DEBUG
"Open BA session requested for %s tid %u\n",
393 print_mac(mac
, ra
), tid
);
394 #endif /* CONFIG_MAC80211_HT_DEBUG */
398 sta
= sta_info_get(local
, ra
);
400 #ifdef CONFIG_MAC80211_HT_DEBUG
401 printk(KERN_DEBUG
"Could not find the station\n");
407 spin_lock_bh(&sta
->lock
);
409 /* we have tried too many times, receiver does not want A-MPDU */
410 if (sta
->ampdu_mlme
.addba_req_num
[tid
] > HT_AGG_MAX_RETRIES
) {
415 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
416 /* check if the TID is not in aggregation flow already */
417 if (*state
!= HT_AGG_STATE_IDLE
) {
418 #ifdef CONFIG_MAC80211_HT_DEBUG
419 printk(KERN_DEBUG
"BA request denied - session is not "
420 "idle on tid %u\n", tid
);
421 #endif /* CONFIG_MAC80211_HT_DEBUG */
426 /* prepare A-MPDU MLME for Tx aggregation */
427 sta
->ampdu_mlme
.tid_tx
[tid
] =
428 kmalloc(sizeof(struct tid_ampdu_tx
), GFP_ATOMIC
);
429 if (!sta
->ampdu_mlme
.tid_tx
[tid
]) {
430 #ifdef CONFIG_MAC80211_HT_DEBUG
432 printk(KERN_ERR
"allocate tx mlme to tid %d failed\n",
439 sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
.function
=
440 sta_addba_resp_timer_expired
;
441 sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
.data
=
442 (unsigned long)&sta
->timer_to_tid
[tid
];
443 init_timer(&sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
);
445 /* create a new queue for this aggregation */
446 ret
= ieee80211_ht_agg_queue_add(local
, sta
, tid
);
448 /* case no queue is available to aggregation
449 * don't switch to aggregation */
451 #ifdef CONFIG_MAC80211_HT_DEBUG
452 printk(KERN_DEBUG
"BA request denied - queue unavailable for"
454 #endif /* CONFIG_MAC80211_HT_DEBUG */
455 goto err_unlock_queue
;
459 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
460 * call back right away, it must see that the flow has begun */
461 *state
|= HT_ADDBA_REQUESTED_MSK
;
463 /* This is slightly racy because the queue isn't stopped */
464 start_seq_num
= sta
->tid_seq
[tid
];
466 if (local
->ops
->ampdu_action
)
467 ret
= local
->ops
->ampdu_action(hw
, IEEE80211_AMPDU_TX_START
,
468 &sta
->sta
, tid
, &start_seq_num
);
471 /* No need to requeue the packets in the agg queue, since we
472 * held the tx lock: no packet could be enqueued to the newly
474 ieee80211_ht_agg_queue_remove(local
, sta
, tid
, 0);
475 #ifdef CONFIG_MAC80211_HT_DEBUG
476 printk(KERN_DEBUG
"BA request denied - HW unavailable for"
478 #endif /* CONFIG_MAC80211_HT_DEBUG */
479 *state
= HT_AGG_STATE_IDLE
;
480 goto err_unlock_queue
;
483 /* Will put all the packets in the new SW queue */
484 ieee80211_requeue(local
, ieee802_1d_to_ac
[tid
]);
485 spin_unlock_bh(&sta
->lock
);
487 /* send an addBA request */
488 sta
->ampdu_mlme
.dialog_token_allocator
++;
489 sta
->ampdu_mlme
.tid_tx
[tid
]->dialog_token
=
490 sta
->ampdu_mlme
.dialog_token_allocator
;
491 sta
->ampdu_mlme
.tid_tx
[tid
]->ssn
= start_seq_num
;
494 ieee80211_send_addba_request(sta
->sdata
, ra
, tid
,
495 sta
->ampdu_mlme
.tid_tx
[tid
]->dialog_token
,
496 sta
->ampdu_mlme
.tid_tx
[tid
]->ssn
,
498 /* activate the timer for the recipient's addBA response */
499 sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
.expires
=
500 jiffies
+ ADDBA_RESP_INTERVAL
;
501 add_timer(&sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
);
502 #ifdef CONFIG_MAC80211_HT_DEBUG
503 printk(KERN_DEBUG
"activated addBA response timer on tid %d\n", tid
);
508 kfree(sta
->ampdu_mlme
.tid_tx
[tid
]);
509 sta
->ampdu_mlme
.tid_tx
[tid
] = NULL
;
512 spin_unlock_bh(&sta
->lock
);
517 EXPORT_SYMBOL(ieee80211_start_tx_ba_session
);
519 int ieee80211_stop_tx_ba_session(struct ieee80211_hw
*hw
,
521 enum ieee80211_back_parties initiator
)
523 struct ieee80211_local
*local
= hw_to_local(hw
);
524 struct sta_info
*sta
;
527 DECLARE_MAC_BUF(mac
);
529 if (tid
>= STA_TID_NUM
)
533 sta
= sta_info_get(local
, ra
);
539 /* check if the TID is in aggregation */
540 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
541 spin_lock_bh(&sta
->lock
);
543 if (*state
!= HT_AGG_STATE_OPERATIONAL
) {
548 #ifdef CONFIG_MAC80211_HT_DEBUG
549 printk(KERN_DEBUG
"Tx BA session stop requested for %s tid %u\n",
550 print_mac(mac
, ra
), tid
);
551 #endif /* CONFIG_MAC80211_HT_DEBUG */
553 ieee80211_stop_queue(hw
, sta
->tid_to_tx_q
[tid
]);
555 *state
= HT_AGG_STATE_REQ_STOP_BA_MSK
|
556 (initiator
<< HT_AGG_STATE_INITIATOR_SHIFT
);
558 if (local
->ops
->ampdu_action
)
559 ret
= local
->ops
->ampdu_action(hw
, IEEE80211_AMPDU_TX_STOP
,
560 &sta
->sta
, tid
, NULL
);
562 /* case HW denied going back to legacy */
564 WARN_ON(ret
!= -EBUSY
);
565 *state
= HT_AGG_STATE_OPERATIONAL
;
566 ieee80211_wake_queue(hw
, sta
->tid_to_tx_q
[tid
]);
571 spin_unlock_bh(&sta
->lock
);
575 EXPORT_SYMBOL(ieee80211_stop_tx_ba_session
);
577 void ieee80211_start_tx_ba_cb(struct ieee80211_hw
*hw
, u8
*ra
, u16 tid
)
579 struct ieee80211_local
*local
= hw_to_local(hw
);
580 struct sta_info
*sta
;
582 DECLARE_MAC_BUF(mac
);
584 if (tid
>= STA_TID_NUM
) {
585 #ifdef CONFIG_MAC80211_HT_DEBUG
586 printk(KERN_DEBUG
"Bad TID value: tid = %d (>= %d)\n",
593 sta
= sta_info_get(local
, ra
);
596 #ifdef CONFIG_MAC80211_HT_DEBUG
597 printk(KERN_DEBUG
"Could not find station: %s\n",
603 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
604 spin_lock_bh(&sta
->lock
);
606 if (!(*state
& HT_ADDBA_REQUESTED_MSK
)) {
607 #ifdef CONFIG_MAC80211_HT_DEBUG
608 printk(KERN_DEBUG
"addBA was not requested yet, state is %d\n",
611 spin_unlock_bh(&sta
->lock
);
616 WARN_ON_ONCE(*state
& HT_ADDBA_DRV_READY_MSK
);
618 *state
|= HT_ADDBA_DRV_READY_MSK
;
620 if (*state
== HT_AGG_STATE_OPERATIONAL
) {
621 #ifdef CONFIG_MAC80211_HT_DEBUG
622 printk(KERN_DEBUG
"Aggregation is on for tid %d \n", tid
);
624 ieee80211_wake_queue(hw
, sta
->tid_to_tx_q
[tid
]);
626 spin_unlock_bh(&sta
->lock
);
629 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb
);
631 void ieee80211_stop_tx_ba_cb(struct ieee80211_hw
*hw
, u8
*ra
, u8 tid
)
633 struct ieee80211_local
*local
= hw_to_local(hw
);
634 struct sta_info
*sta
;
637 DECLARE_MAC_BUF(mac
);
639 if (tid
>= STA_TID_NUM
) {
640 #ifdef CONFIG_MAC80211_HT_DEBUG
641 printk(KERN_DEBUG
"Bad TID value: tid = %d (>= %d)\n",
647 #ifdef CONFIG_MAC80211_HT_DEBUG
648 printk(KERN_DEBUG
"Stopping Tx BA session for %s tid %d\n",
649 print_mac(mac
, ra
), tid
);
650 #endif /* CONFIG_MAC80211_HT_DEBUG */
653 sta
= sta_info_get(local
, ra
);
655 #ifdef CONFIG_MAC80211_HT_DEBUG
656 printk(KERN_DEBUG
"Could not find station: %s\n",
662 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
664 /* NOTE: no need to use sta->lock in this state check, as
665 * ieee80211_stop_tx_ba_session will let only one stop call to
666 * pass through per sta/tid
668 if ((*state
& HT_AGG_STATE_REQ_STOP_BA_MSK
) == 0) {
669 #ifdef CONFIG_MAC80211_HT_DEBUG
670 printk(KERN_DEBUG
"unexpected callback to A-MPDU stop\n");
676 if (*state
& HT_AGG_STATE_INITIATOR_MSK
)
677 ieee80211_send_delba(sta
->sdata
, ra
, tid
,
678 WLAN_BACK_INITIATOR
, WLAN_REASON_QSTA_NOT_USE
);
680 agg_queue
= sta
->tid_to_tx_q
[tid
];
682 ieee80211_ht_agg_queue_remove(local
, sta
, tid
, 1);
684 /* We just requeued the all the frames that were in the
685 * removed queue, and since we might miss a softirq we do
686 * netif_schedule_queue. ieee80211_wake_queue is not used
687 * here as this queue is not necessarily stopped
689 netif_schedule_queue(netdev_get_tx_queue(local
->mdev
, agg_queue
));
690 spin_lock_bh(&sta
->lock
);
691 *state
= HT_AGG_STATE_IDLE
;
692 sta
->ampdu_mlme
.addba_req_num
[tid
] = 0;
693 kfree(sta
->ampdu_mlme
.tid_tx
[tid
]);
694 sta
->ampdu_mlme
.tid_tx
[tid
] = NULL
;
695 spin_unlock_bh(&sta
->lock
);
699 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb
);
701 void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw
*hw
,
702 const u8
*ra
, u16 tid
)
704 struct ieee80211_local
*local
= hw_to_local(hw
);
705 struct ieee80211_ra_tid
*ra_tid
;
706 struct sk_buff
*skb
= dev_alloc_skb(0);
708 if (unlikely(!skb
)) {
709 #ifdef CONFIG_MAC80211_HT_DEBUG
711 printk(KERN_WARNING
"%s: Not enough memory, "
712 "dropping start BA session", skb
->dev
->name
);
716 ra_tid
= (struct ieee80211_ra_tid
*) &skb
->cb
;
717 memcpy(&ra_tid
->ra
, ra
, ETH_ALEN
);
720 skb
->pkt_type
= IEEE80211_ADDBA_MSG
;
721 skb_queue_tail(&local
->skb_queue
, skb
);
722 tasklet_schedule(&local
->tasklet
);
724 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe
);
726 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw
*hw
,
727 const u8
*ra
, u16 tid
)
729 struct ieee80211_local
*local
= hw_to_local(hw
);
730 struct ieee80211_ra_tid
*ra_tid
;
731 struct sk_buff
*skb
= dev_alloc_skb(0);
733 if (unlikely(!skb
)) {
734 #ifdef CONFIG_MAC80211_HT_DEBUG
736 printk(KERN_WARNING
"%s: Not enough memory, "
737 "dropping stop BA session", skb
->dev
->name
);
741 ra_tid
= (struct ieee80211_ra_tid
*) &skb
->cb
;
742 memcpy(&ra_tid
->ra
, ra
, ETH_ALEN
);
745 skb
->pkt_type
= IEEE80211_DELBA_MSG
;
746 skb_queue_tail(&local
->skb_queue
, skb
);
747 tasklet_schedule(&local
->tasklet
);
749 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe
);
752 * After accepting the AddBA Request we activated a timer,
753 * resetting it after each frame that arrives from the originator.
754 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
756 static void sta_rx_agg_session_timer_expired(unsigned long data
)
758 /* not an elegant detour, but there is no choice as the timer passes
759 * only one argument, and various sta_info are needed here, so init
760 * flow in sta_info_create gives the TID as data, while the timer_to_id
761 * array gives the sta through container_of */
762 u8
*ptid
= (u8
*)data
;
763 u8
*timer_to_id
= ptid
- *ptid
;
764 struct sta_info
*sta
= container_of(timer_to_id
, struct sta_info
,
767 #ifdef CONFIG_MAC80211_HT_DEBUG
768 printk(KERN_DEBUG
"rx session timer expired on tid %d\n", (u16
)*ptid
);
770 ieee80211_sta_stop_rx_ba_session(sta
->sdata
, sta
->sta
.addr
,
771 (u16
)*ptid
, WLAN_BACK_TIMER
,
772 WLAN_REASON_QSTA_TIMEOUT
);
775 void ieee80211_process_addba_request(struct ieee80211_local
*local
,
776 struct sta_info
*sta
,
777 struct ieee80211_mgmt
*mgmt
,
780 struct ieee80211_hw
*hw
= &local
->hw
;
781 struct ieee80211_conf
*conf
= &hw
->conf
;
782 struct tid_ampdu_rx
*tid_agg_rx
;
783 u16 capab
, tid
, timeout
, ba_policy
, buf_size
, start_seq_num
, status
;
785 int ret
= -EOPNOTSUPP
;
786 DECLARE_MAC_BUF(mac
);
788 /* extract session parameters from addba request frame */
789 dialog_token
= mgmt
->u
.action
.u
.addba_req
.dialog_token
;
790 timeout
= le16_to_cpu(mgmt
->u
.action
.u
.addba_req
.timeout
);
792 le16_to_cpu(mgmt
->u
.action
.u
.addba_req
.start_seq_num
) >> 4;
794 capab
= le16_to_cpu(mgmt
->u
.action
.u
.addba_req
.capab
);
795 ba_policy
= (capab
& IEEE80211_ADDBA_PARAM_POLICY_MASK
) >> 1;
796 tid
= (capab
& IEEE80211_ADDBA_PARAM_TID_MASK
) >> 2;
797 buf_size
= (capab
& IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
) >> 6;
799 status
= WLAN_STATUS_REQUEST_DECLINED
;
801 /* sanity check for incoming parameters:
802 * check if configuration can support the BA policy
803 * and if buffer size does not exceeds max value */
804 if (((ba_policy
!= 1)
805 && (!(conf
->ht_conf
.cap
& IEEE80211_HT_CAP_DELAY_BA
)))
806 || (buf_size
> IEEE80211_MAX_AMPDU_BUF
)) {
807 status
= WLAN_STATUS_INVALID_QOS_PARAM
;
808 #ifdef CONFIG_MAC80211_HT_DEBUG
810 printk(KERN_DEBUG
"AddBA Req with bad params from "
811 "%s on tid %u. policy %d, buffer size %d\n",
812 print_mac(mac
, mgmt
->sa
), tid
, ba_policy
,
814 #endif /* CONFIG_MAC80211_HT_DEBUG */
817 /* determine default buffer size */
819 struct ieee80211_supported_band
*sband
;
821 sband
= local
->hw
.wiphy
->bands
[conf
->channel
->band
];
822 buf_size
= IEEE80211_MIN_AMPDU_BUF
;
823 buf_size
= buf_size
<< sband
->ht_info
.ampdu_factor
;
827 /* examine state machine */
828 spin_lock_bh(&sta
->lock
);
830 if (sta
->ampdu_mlme
.tid_state_rx
[tid
] != HT_AGG_STATE_IDLE
) {
831 #ifdef CONFIG_MAC80211_HT_DEBUG
833 printk(KERN_DEBUG
"unexpected AddBA Req from "
835 print_mac(mac
, mgmt
->sa
), tid
);
836 #endif /* CONFIG_MAC80211_HT_DEBUG */
840 /* prepare A-MPDU MLME for Rx aggregation */
841 sta
->ampdu_mlme
.tid_rx
[tid
] =
842 kmalloc(sizeof(struct tid_ampdu_rx
), GFP_ATOMIC
);
843 if (!sta
->ampdu_mlme
.tid_rx
[tid
]) {
844 #ifdef CONFIG_MAC80211_HT_DEBUG
846 printk(KERN_ERR
"allocate rx mlme to tid %d failed\n",
852 sta
->ampdu_mlme
.tid_rx
[tid
]->session_timer
.function
=
853 sta_rx_agg_session_timer_expired
;
854 sta
->ampdu_mlme
.tid_rx
[tid
]->session_timer
.data
=
855 (unsigned long)&sta
->timer_to_tid
[tid
];
856 init_timer(&sta
->ampdu_mlme
.tid_rx
[tid
]->session_timer
);
858 tid_agg_rx
= sta
->ampdu_mlme
.tid_rx
[tid
];
860 /* prepare reordering buffer */
861 tid_agg_rx
->reorder_buf
=
862 kmalloc(buf_size
* sizeof(struct sk_buff
*), GFP_ATOMIC
);
863 if (!tid_agg_rx
->reorder_buf
) {
864 #ifdef CONFIG_MAC80211_HT_DEBUG
866 printk(KERN_ERR
"can not allocate reordering buffer "
869 kfree(sta
->ampdu_mlme
.tid_rx
[tid
]);
872 memset(tid_agg_rx
->reorder_buf
, 0,
873 buf_size
* sizeof(struct sk_buff
*));
875 if (local
->ops
->ampdu_action
)
876 ret
= local
->ops
->ampdu_action(hw
, IEEE80211_AMPDU_RX_START
,
877 &sta
->sta
, tid
, &start_seq_num
);
878 #ifdef CONFIG_MAC80211_HT_DEBUG
879 printk(KERN_DEBUG
"Rx A-MPDU request on tid %d result %d\n", tid
, ret
);
880 #endif /* CONFIG_MAC80211_HT_DEBUG */
883 kfree(tid_agg_rx
->reorder_buf
);
885 sta
->ampdu_mlme
.tid_rx
[tid
] = NULL
;
889 /* change state and send addba resp */
890 sta
->ampdu_mlme
.tid_state_rx
[tid
] = HT_AGG_STATE_OPERATIONAL
;
891 tid_agg_rx
->dialog_token
= dialog_token
;
892 tid_agg_rx
->ssn
= start_seq_num
;
893 tid_agg_rx
->head_seq_num
= start_seq_num
;
894 tid_agg_rx
->buf_size
= buf_size
;
895 tid_agg_rx
->timeout
= timeout
;
896 tid_agg_rx
->stored_mpdu_num
= 0;
897 status
= WLAN_STATUS_SUCCESS
;
899 spin_unlock_bh(&sta
->lock
);
902 ieee80211_send_addba_resp(sta
->sdata
, sta
->sta
.addr
, tid
,
903 dialog_token
, status
, 1, buf_size
, timeout
);
906 void ieee80211_process_addba_resp(struct ieee80211_local
*local
,
907 struct sta_info
*sta
,
908 struct ieee80211_mgmt
*mgmt
,
911 struct ieee80211_hw
*hw
= &local
->hw
;
916 capab
= le16_to_cpu(mgmt
->u
.action
.u
.addba_resp
.capab
);
917 tid
= (capab
& IEEE80211_ADDBA_PARAM_TID_MASK
) >> 2;
919 state
= &sta
->ampdu_mlme
.tid_state_tx
[tid
];
921 spin_lock_bh(&sta
->lock
);
923 if (!(*state
& HT_ADDBA_REQUESTED_MSK
)) {
924 spin_unlock_bh(&sta
->lock
);
928 if (mgmt
->u
.action
.u
.addba_resp
.dialog_token
!=
929 sta
->ampdu_mlme
.tid_tx
[tid
]->dialog_token
) {
930 spin_unlock_bh(&sta
->lock
);
931 #ifdef CONFIG_MAC80211_HT_DEBUG
932 printk(KERN_DEBUG
"wrong addBA response token, tid %d\n", tid
);
933 #endif /* CONFIG_MAC80211_HT_DEBUG */
937 del_timer_sync(&sta
->ampdu_mlme
.tid_tx
[tid
]->addba_resp_timer
);
938 #ifdef CONFIG_MAC80211_HT_DEBUG
939 printk(KERN_DEBUG
"switched off addBA timer for tid %d \n", tid
);
940 #endif /* CONFIG_MAC80211_HT_DEBUG */
941 if (le16_to_cpu(mgmt
->u
.action
.u
.addba_resp
.status
)
942 == WLAN_STATUS_SUCCESS
) {
943 *state
|= HT_ADDBA_RECEIVED_MSK
;
944 sta
->ampdu_mlme
.addba_req_num
[tid
] = 0;
946 if (*state
== HT_AGG_STATE_OPERATIONAL
)
947 ieee80211_wake_queue(hw
, sta
->tid_to_tx_q
[tid
]);
949 spin_unlock_bh(&sta
->lock
);
951 sta
->ampdu_mlme
.addba_req_num
[tid
]++;
952 /* this will allow the state check in stop_BA_session */
953 *state
= HT_AGG_STATE_OPERATIONAL
;
954 spin_unlock_bh(&sta
->lock
);
955 ieee80211_stop_tx_ba_session(hw
, sta
->sta
.addr
, tid
,
956 WLAN_BACK_INITIATOR
);
960 void ieee80211_process_delba(struct ieee80211_sub_if_data
*sdata
,
961 struct sta_info
*sta
,
962 struct ieee80211_mgmt
*mgmt
, size_t len
)
964 struct ieee80211_local
*local
= sdata
->local
;
967 DECLARE_MAC_BUF(mac
);
969 params
= le16_to_cpu(mgmt
->u
.action
.u
.delba
.params
);
970 tid
= (params
& IEEE80211_DELBA_PARAM_TID_MASK
) >> 12;
971 initiator
= (params
& IEEE80211_DELBA_PARAM_INITIATOR_MASK
) >> 11;
973 #ifdef CONFIG_MAC80211_HT_DEBUG
975 printk(KERN_DEBUG
"delba from %s (%s) tid %d reason code %d\n",
976 print_mac(mac
, mgmt
->sa
),
977 initiator
? "initiator" : "recipient", tid
,
978 mgmt
->u
.action
.u
.delba
.reason_code
);
979 #endif /* CONFIG_MAC80211_HT_DEBUG */
981 if (initiator
== WLAN_BACK_INITIATOR
)
982 ieee80211_sta_stop_rx_ba_session(sdata
, sta
->sta
.addr
, tid
,
983 WLAN_BACK_INITIATOR
, 0);
984 else { /* WLAN_BACK_RECIPIENT */
985 spin_lock_bh(&sta
->lock
);
986 sta
->ampdu_mlme
.tid_state_tx
[tid
] =
987 HT_AGG_STATE_OPERATIONAL
;
988 spin_unlock_bh(&sta
->lock
);
989 ieee80211_stop_tx_ba_session(&local
->hw
, sta
->sta
.addr
, tid
,
990 WLAN_BACK_RECIPIENT
);