VM, x86, PAT: add a new vm flag to track full pfnmap at mmap
[linux-2.6/mini2440.git] / net / mac80211 / ht.c
blobc5c0c5271096ca7ae3369c2d99b0eeafe34bd413
1 /*
2 * HT handling
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"
20 #include "sta_info.h"
21 #include "wme.h"
23 void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
24 struct ieee80211_ht_cap *ht_cap_ie,
25 struct ieee80211_sta_ht_cap *ht_cap)
27 u8 ampdu_info, tx_mcs_set_cap;
28 int i, max_tx_streams;
30 BUG_ON(!ht_cap);
32 memset(ht_cap, 0, sizeof(*ht_cap));
34 if (!ht_cap_ie)
35 return;
37 ht_cap->ht_supported = true;
39 ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) & sband->ht_cap.cap;
40 ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS;
41 ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS;
43 ampdu_info = ht_cap_ie->ampdu_params_info;
44 ht_cap->ampdu_factor =
45 ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR;
46 ht_cap->ampdu_density =
47 (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
49 /* own MCS TX capabilities */
50 tx_mcs_set_cap = sband->ht_cap.mcs.tx_params;
52 /* can we TX with MCS rates? */
53 if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED))
54 return;
56 /* Counting from 0, therefore +1 */
57 if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_RX_DIFF)
58 max_tx_streams =
59 ((tx_mcs_set_cap & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
60 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1;
61 else
62 max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS;
65 * 802.11n D5.0 20.3.5 / 20.6 says:
66 * - indices 0 to 7 and 32 are single spatial stream
67 * - 8 to 31 are multiple spatial streams using equal modulation
68 * [8..15 for two streams, 16..23 for three and 24..31 for four]
69 * - remainder are multiple spatial streams using unequal modulation
71 for (i = 0; i < max_tx_streams; i++)
72 ht_cap->mcs.rx_mask[i] =
73 sband->ht_cap.mcs.rx_mask[i] & ht_cap_ie->mcs.rx_mask[i];
75 if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION)
76 for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE;
77 i < IEEE80211_HT_MCS_MASK_LEN; i++)
78 ht_cap->mcs.rx_mask[i] =
79 sband->ht_cap.mcs.rx_mask[i] &
80 ht_cap_ie->mcs.rx_mask[i];
82 /* handle MCS rate 32 too */
83 if (sband->ht_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1)
84 ht_cap->mcs.rx_mask[32/8] |= 1;
88 * ieee80211_enable_ht should be called only after the operating band
89 * has been determined as ht configuration depends on the hw's
90 * HT abilities for a specific band.
92 u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
93 struct ieee80211_ht_info *hti,
94 u16 ap_ht_cap_flags)
96 struct ieee80211_local *local = sdata->local;
97 struct ieee80211_supported_band *sband;
98 struct ieee80211_bss_ht_conf ht;
99 u32 changed = 0;
100 bool enable_ht = true, ht_changed;
101 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
103 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
105 memset(&ht, 0, sizeof(ht));
107 /* HT is not supported */
108 if (!sband->ht_cap.ht_supported)
109 enable_ht = false;
111 /* check that channel matches the right operating channel */
112 if (local->hw.conf.channel->center_freq !=
113 ieee80211_channel_to_frequency(hti->control_chan))
114 enable_ht = false;
116 if (enable_ht) {
117 channel_type = NL80211_CHAN_HT20;
119 if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
120 (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
121 (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
122 switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
123 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
124 channel_type = NL80211_CHAN_HT40PLUS;
125 break;
126 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
127 channel_type = NL80211_CHAN_HT40MINUS;
128 break;
133 ht_changed = local->hw.conf.ht.enabled != enable_ht ||
134 channel_type != local->hw.conf.ht.channel_type;
136 local->oper_channel_type = channel_type;
137 local->hw.conf.ht.enabled = enable_ht;
139 if (ht_changed)
140 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT);
142 /* disable HT */
143 if (!enable_ht)
144 return 0;
146 ht.operation_mode = le16_to_cpu(hti->operation_mode);
148 /* if bss configuration changed store the new one */
149 if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {
150 changed |= BSS_CHANGED_HT;
151 sdata->vif.bss_conf.ht = ht;
154 return changed;
157 static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
158 const u8 *da, u16 tid,
159 u8 dialog_token, u16 start_seq_num,
160 u16 agg_size, u16 timeout)
162 struct ieee80211_local *local = sdata->local;
163 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
164 struct sk_buff *skb;
165 struct ieee80211_mgmt *mgmt;
166 u16 capab;
168 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
170 if (!skb) {
171 printk(KERN_ERR "%s: failed to allocate buffer "
172 "for addba request frame\n", sdata->dev->name);
173 return;
175 skb_reserve(skb, local->hw.extra_tx_headroom);
176 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
177 memset(mgmt, 0, 24);
178 memcpy(mgmt->da, da, ETH_ALEN);
179 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
180 if (sdata->vif.type == NL80211_IFTYPE_AP)
181 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
182 else
183 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
185 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
186 IEEE80211_STYPE_ACTION);
188 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
190 mgmt->u.action.category = WLAN_CATEGORY_BACK;
191 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
193 mgmt->u.action.u.addba_req.dialog_token = dialog_token;
194 capab = (u16)(1 << 1); /* bit 1 aggregation policy */
195 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
196 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
198 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
200 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
201 mgmt->u.action.u.addba_req.start_seq_num =
202 cpu_to_le16(start_seq_num << 4);
204 ieee80211_tx_skb(sdata, skb, 0);
207 static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
208 u8 dialog_token, u16 status, u16 policy,
209 u16 buf_size, u16 timeout)
211 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
212 struct ieee80211_local *local = sdata->local;
213 struct sk_buff *skb;
214 struct ieee80211_mgmt *mgmt;
215 u16 capab;
217 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
219 if (!skb) {
220 printk(KERN_DEBUG "%s: failed to allocate buffer "
221 "for addba resp frame\n", sdata->dev->name);
222 return;
225 skb_reserve(skb, local->hw.extra_tx_headroom);
226 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
227 memset(mgmt, 0, 24);
228 memcpy(mgmt->da, da, ETH_ALEN);
229 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
230 if (sdata->vif.type == NL80211_IFTYPE_AP)
231 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
232 else
233 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
234 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
235 IEEE80211_STYPE_ACTION);
237 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
238 mgmt->u.action.category = WLAN_CATEGORY_BACK;
239 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
240 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
242 capab = (u16)(policy << 1); /* bit 1 aggregation policy */
243 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
244 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
246 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
247 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
248 mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
250 ieee80211_tx_skb(sdata, skb, 0);
253 static void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
254 const u8 *da, u16 tid,
255 u16 initiator, u16 reason_code)
257 struct ieee80211_local *local = sdata->local;
258 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
259 struct sk_buff *skb;
260 struct ieee80211_mgmt *mgmt;
261 u16 params;
263 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
265 if (!skb) {
266 printk(KERN_ERR "%s: failed to allocate buffer "
267 "for delba frame\n", sdata->dev->name);
268 return;
271 skb_reserve(skb, local->hw.extra_tx_headroom);
272 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
273 memset(mgmt, 0, 24);
274 memcpy(mgmt->da, da, ETH_ALEN);
275 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
276 if (sdata->vif.type == NL80211_IFTYPE_AP)
277 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
278 else
279 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
280 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
281 IEEE80211_STYPE_ACTION);
283 skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
285 mgmt->u.action.category = WLAN_CATEGORY_BACK;
286 mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
287 params = (u16)(initiator << 11); /* bit 11 initiator */
288 params |= (u16)(tid << 12); /* bit 15:12 TID number */
290 mgmt->u.action.u.delba.params = cpu_to_le16(params);
291 mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
293 ieee80211_tx_skb(sdata, skb, 0);
296 void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
298 struct ieee80211_local *local = sdata->local;
299 struct sk_buff *skb;
300 struct ieee80211_bar *bar;
301 u16 bar_control = 0;
303 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
304 if (!skb) {
305 printk(KERN_ERR "%s: failed to allocate buffer for "
306 "bar frame\n", sdata->dev->name);
307 return;
309 skb_reserve(skb, local->hw.extra_tx_headroom);
310 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
311 memset(bar, 0, sizeof(*bar));
312 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
313 IEEE80211_STYPE_BACK_REQ);
314 memcpy(bar->ra, ra, ETH_ALEN);
315 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
316 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
317 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
318 bar_control |= (u16)(tid << 12);
319 bar->control = cpu_to_le16(bar_control);
320 bar->start_seq_num = cpu_to_le16(ssn);
322 ieee80211_tx_skb(sdata, skb, 0);
325 void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
326 u16 initiator, u16 reason)
328 struct ieee80211_local *local = sdata->local;
329 struct ieee80211_hw *hw = &local->hw;
330 struct sta_info *sta;
331 int ret, i;
333 rcu_read_lock();
335 sta = sta_info_get(local, ra);
336 if (!sta) {
337 rcu_read_unlock();
338 return;
341 /* check if TID is in operational state */
342 spin_lock_bh(&sta->lock);
343 if (sta->ampdu_mlme.tid_state_rx[tid]
344 != HT_AGG_STATE_OPERATIONAL) {
345 spin_unlock_bh(&sta->lock);
346 rcu_read_unlock();
347 return;
349 sta->ampdu_mlme.tid_state_rx[tid] =
350 HT_AGG_STATE_REQ_STOP_BA_MSK |
351 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
352 spin_unlock_bh(&sta->lock);
354 /* stop HW Rx aggregation. ampdu_action existence
355 * already verified in session init so we add the BUG_ON */
356 BUG_ON(!local->ops->ampdu_action);
358 #ifdef CONFIG_MAC80211_HT_DEBUG
359 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
360 ra, tid);
361 #endif /* CONFIG_MAC80211_HT_DEBUG */
363 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
364 &sta->sta, tid, NULL);
365 if (ret)
366 printk(KERN_DEBUG "HW problem - can not stop rx "
367 "aggregation for tid %d\n", tid);
369 /* shutdown timer has not expired */
370 if (initiator != WLAN_BACK_TIMER)
371 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
373 /* check if this is a self generated aggregation halt */
374 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
375 ieee80211_send_delba(sdata, ra, tid, 0, reason);
377 /* free the reordering buffer */
378 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
379 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
380 /* release the reordered frames */
381 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
382 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
383 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
386 /* free resources */
387 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
388 kfree(sta->ampdu_mlme.tid_rx[tid]);
389 sta->ampdu_mlme.tid_rx[tid] = NULL;
390 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
392 rcu_read_unlock();
397 * After sending add Block Ack request we activated a timer until
398 * add Block Ack response will arrive from the recipient.
399 * If this timer expires sta_addba_resp_timer_expired will be executed.
401 static void sta_addba_resp_timer_expired(unsigned long data)
403 /* not an elegant detour, but there is no choice as the timer passes
404 * only one argument, and both sta_info and TID are needed, so init
405 * flow in sta_info_create gives the TID as data, while the timer_to_id
406 * array gives the sta through container_of */
407 u16 tid = *(u8 *)data;
408 struct sta_info *temp_sta = container_of((void *)data,
409 struct sta_info, timer_to_tid[tid]);
411 struct ieee80211_local *local = temp_sta->local;
412 struct ieee80211_hw *hw = &local->hw;
413 struct sta_info *sta;
414 u8 *state;
416 rcu_read_lock();
418 sta = sta_info_get(local, temp_sta->sta.addr);
419 if (!sta) {
420 rcu_read_unlock();
421 return;
424 state = &sta->ampdu_mlme.tid_state_tx[tid];
425 /* check if the TID waits for addBA response */
426 spin_lock_bh(&sta->lock);
427 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
428 spin_unlock_bh(&sta->lock);
429 *state = HT_AGG_STATE_IDLE;
430 #ifdef CONFIG_MAC80211_HT_DEBUG
431 printk(KERN_DEBUG "timer expired on tid %d but we are not "
432 "expecting addBA response there", tid);
433 #endif
434 goto timer_expired_exit;
437 #ifdef CONFIG_MAC80211_HT_DEBUG
438 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
439 #endif
441 /* go through the state check in stop_BA_session */
442 *state = HT_AGG_STATE_OPERATIONAL;
443 spin_unlock_bh(&sta->lock);
444 ieee80211_stop_tx_ba_session(hw, temp_sta->sta.addr, tid,
445 WLAN_BACK_INITIATOR);
447 timer_expired_exit:
448 rcu_read_unlock();
451 void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
453 struct ieee80211_local *local = sdata->local;
454 int i;
456 for (i = 0; i < STA_TID_NUM; i++) {
457 ieee80211_stop_tx_ba_session(&local->hw, addr, i,
458 WLAN_BACK_INITIATOR);
459 ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
460 WLAN_BACK_RECIPIENT,
461 WLAN_REASON_QSTA_LEAVE_QBSS);
465 int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
467 struct ieee80211_local *local = hw_to_local(hw);
468 struct sta_info *sta;
469 struct ieee80211_sub_if_data *sdata;
470 u16 start_seq_num;
471 u8 *state;
472 int ret = 0;
474 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
475 return -EINVAL;
477 #ifdef CONFIG_MAC80211_HT_DEBUG
478 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
479 ra, tid);
480 #endif /* CONFIG_MAC80211_HT_DEBUG */
482 rcu_read_lock();
484 sta = sta_info_get(local, ra);
485 if (!sta) {
486 #ifdef CONFIG_MAC80211_HT_DEBUG
487 printk(KERN_DEBUG "Could not find the station\n");
488 #endif
489 ret = -ENOENT;
490 goto exit;
493 spin_lock_bh(&sta->lock);
495 /* we have tried too many times, receiver does not want A-MPDU */
496 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
497 ret = -EBUSY;
498 goto err_unlock_sta;
501 state = &sta->ampdu_mlme.tid_state_tx[tid];
502 /* check if the TID is not in aggregation flow already */
503 if (*state != HT_AGG_STATE_IDLE) {
504 #ifdef CONFIG_MAC80211_HT_DEBUG
505 printk(KERN_DEBUG "BA request denied - session is not "
506 "idle on tid %u\n", tid);
507 #endif /* CONFIG_MAC80211_HT_DEBUG */
508 ret = -EAGAIN;
509 goto err_unlock_sta;
512 /* prepare A-MPDU MLME for Tx aggregation */
513 sta->ampdu_mlme.tid_tx[tid] =
514 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
515 if (!sta->ampdu_mlme.tid_tx[tid]) {
516 #ifdef CONFIG_MAC80211_HT_DEBUG
517 if (net_ratelimit())
518 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
519 tid);
520 #endif
521 ret = -ENOMEM;
522 goto err_unlock_sta;
524 /* Tx timer */
525 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
526 sta_addba_resp_timer_expired;
527 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
528 (unsigned long)&sta->timer_to_tid[tid];
529 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
531 if (hw->ampdu_queues) {
532 /* create a new queue for this aggregation */
533 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
535 /* case no queue is available to aggregation
536 * don't switch to aggregation */
537 if (ret) {
538 #ifdef CONFIG_MAC80211_HT_DEBUG
539 printk(KERN_DEBUG "BA request denied - "
540 "queue unavailable for tid %d\n", tid);
541 #endif /* CONFIG_MAC80211_HT_DEBUG */
542 goto err_unlock_queue;
545 sdata = sta->sdata;
547 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
548 * call back right away, it must see that the flow has begun */
549 *state |= HT_ADDBA_REQUESTED_MSK;
551 /* This is slightly racy because the queue isn't stopped */
552 start_seq_num = sta->tid_seq[tid];
554 if (local->ops->ampdu_action)
555 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
556 &sta->sta, tid, &start_seq_num);
558 if (ret) {
559 /* No need to requeue the packets in the agg queue, since we
560 * held the tx lock: no packet could be enqueued to the newly
561 * allocated queue */
562 if (hw->ampdu_queues)
563 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
564 #ifdef CONFIG_MAC80211_HT_DEBUG
565 printk(KERN_DEBUG "BA request denied - HW unavailable for"
566 " tid %d\n", tid);
567 #endif /* CONFIG_MAC80211_HT_DEBUG */
568 *state = HT_AGG_STATE_IDLE;
569 goto err_unlock_queue;
572 /* Will put all the packets in the new SW queue */
573 if (hw->ampdu_queues)
574 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
575 spin_unlock_bh(&sta->lock);
577 /* send an addBA request */
578 sta->ampdu_mlme.dialog_token_allocator++;
579 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
580 sta->ampdu_mlme.dialog_token_allocator;
581 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
584 ieee80211_send_addba_request(sta->sdata, ra, tid,
585 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
586 sta->ampdu_mlme.tid_tx[tid]->ssn,
587 0x40, 5000);
588 /* activate the timer for the recipient's addBA response */
589 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
590 jiffies + ADDBA_RESP_INTERVAL;
591 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
592 #ifdef CONFIG_MAC80211_HT_DEBUG
593 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
594 #endif
595 goto exit;
597 err_unlock_queue:
598 kfree(sta->ampdu_mlme.tid_tx[tid]);
599 sta->ampdu_mlme.tid_tx[tid] = NULL;
600 ret = -EBUSY;
601 err_unlock_sta:
602 spin_unlock_bh(&sta->lock);
603 exit:
604 rcu_read_unlock();
605 return ret;
607 EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
609 int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
610 u8 *ra, u16 tid,
611 enum ieee80211_back_parties initiator)
613 struct ieee80211_local *local = hw_to_local(hw);
614 struct sta_info *sta;
615 u8 *state;
616 int ret = 0;
618 if (tid >= STA_TID_NUM)
619 return -EINVAL;
621 rcu_read_lock();
622 sta = sta_info_get(local, ra);
623 if (!sta) {
624 rcu_read_unlock();
625 return -ENOENT;
628 /* check if the TID is in aggregation */
629 state = &sta->ampdu_mlme.tid_state_tx[tid];
630 spin_lock_bh(&sta->lock);
632 if (*state != HT_AGG_STATE_OPERATIONAL) {
633 ret = -ENOENT;
634 goto stop_BA_exit;
637 #ifdef CONFIG_MAC80211_HT_DEBUG
638 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
639 ra, tid);
640 #endif /* CONFIG_MAC80211_HT_DEBUG */
642 if (hw->ampdu_queues)
643 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
645 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
646 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
648 if (local->ops->ampdu_action)
649 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
650 &sta->sta, tid, NULL);
652 /* case HW denied going back to legacy */
653 if (ret) {
654 WARN_ON(ret != -EBUSY);
655 *state = HT_AGG_STATE_OPERATIONAL;
656 if (hw->ampdu_queues)
657 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
658 goto stop_BA_exit;
661 stop_BA_exit:
662 spin_unlock_bh(&sta->lock);
663 rcu_read_unlock();
664 return ret;
666 EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
668 void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
670 struct ieee80211_local *local = hw_to_local(hw);
671 struct sta_info *sta;
672 u8 *state;
674 if (tid >= STA_TID_NUM) {
675 #ifdef CONFIG_MAC80211_HT_DEBUG
676 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
677 tid, STA_TID_NUM);
678 #endif
679 return;
682 rcu_read_lock();
683 sta = sta_info_get(local, ra);
684 if (!sta) {
685 rcu_read_unlock();
686 #ifdef CONFIG_MAC80211_HT_DEBUG
687 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
688 #endif
689 return;
692 state = &sta->ampdu_mlme.tid_state_tx[tid];
693 spin_lock_bh(&sta->lock);
695 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
696 #ifdef CONFIG_MAC80211_HT_DEBUG
697 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
698 *state);
699 #endif
700 spin_unlock_bh(&sta->lock);
701 rcu_read_unlock();
702 return;
705 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
707 *state |= HT_ADDBA_DRV_READY_MSK;
709 if (*state == HT_AGG_STATE_OPERATIONAL) {
710 #ifdef CONFIG_MAC80211_HT_DEBUG
711 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
712 #endif
713 if (hw->ampdu_queues)
714 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
716 spin_unlock_bh(&sta->lock);
717 rcu_read_unlock();
719 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
721 void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
723 struct ieee80211_local *local = hw_to_local(hw);
724 struct sta_info *sta;
725 u8 *state;
726 int agg_queue;
728 if (tid >= STA_TID_NUM) {
729 #ifdef CONFIG_MAC80211_HT_DEBUG
730 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
731 tid, STA_TID_NUM);
732 #endif
733 return;
736 #ifdef CONFIG_MAC80211_HT_DEBUG
737 printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
738 ra, tid);
739 #endif /* CONFIG_MAC80211_HT_DEBUG */
741 rcu_read_lock();
742 sta = sta_info_get(local, ra);
743 if (!sta) {
744 #ifdef CONFIG_MAC80211_HT_DEBUG
745 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
746 #endif
747 rcu_read_unlock();
748 return;
750 state = &sta->ampdu_mlme.tid_state_tx[tid];
752 /* NOTE: no need to use sta->lock in this state check, as
753 * ieee80211_stop_tx_ba_session will let only one stop call to
754 * pass through per sta/tid
756 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
757 #ifdef CONFIG_MAC80211_HT_DEBUG
758 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
759 #endif
760 rcu_read_unlock();
761 return;
764 if (*state & HT_AGG_STATE_INITIATOR_MSK)
765 ieee80211_send_delba(sta->sdata, ra, tid,
766 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
768 if (hw->ampdu_queues) {
769 agg_queue = sta->tid_to_tx_q[tid];
770 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
772 /* We just requeued the all the frames that were in the
773 * removed queue, and since we might miss a softirq we do
774 * netif_schedule_queue. ieee80211_wake_queue is not used
775 * here as this queue is not necessarily stopped
777 netif_schedule_queue(netdev_get_tx_queue(local->mdev,
778 agg_queue));
780 spin_lock_bh(&sta->lock);
781 *state = HT_AGG_STATE_IDLE;
782 sta->ampdu_mlme.addba_req_num[tid] = 0;
783 kfree(sta->ampdu_mlme.tid_tx[tid]);
784 sta->ampdu_mlme.tid_tx[tid] = NULL;
785 spin_unlock_bh(&sta->lock);
787 rcu_read_unlock();
789 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
791 void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
792 const u8 *ra, u16 tid)
794 struct ieee80211_local *local = hw_to_local(hw);
795 struct ieee80211_ra_tid *ra_tid;
796 struct sk_buff *skb = dev_alloc_skb(0);
798 if (unlikely(!skb)) {
799 #ifdef CONFIG_MAC80211_HT_DEBUG
800 if (net_ratelimit())
801 printk(KERN_WARNING "%s: Not enough memory, "
802 "dropping start BA session", skb->dev->name);
803 #endif
804 return;
806 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
807 memcpy(&ra_tid->ra, ra, ETH_ALEN);
808 ra_tid->tid = tid;
810 skb->pkt_type = IEEE80211_ADDBA_MSG;
811 skb_queue_tail(&local->skb_queue, skb);
812 tasklet_schedule(&local->tasklet);
814 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
816 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
817 const u8 *ra, u16 tid)
819 struct ieee80211_local *local = hw_to_local(hw);
820 struct ieee80211_ra_tid *ra_tid;
821 struct sk_buff *skb = dev_alloc_skb(0);
823 if (unlikely(!skb)) {
824 #ifdef CONFIG_MAC80211_HT_DEBUG
825 if (net_ratelimit())
826 printk(KERN_WARNING "%s: Not enough memory, "
827 "dropping stop BA session", skb->dev->name);
828 #endif
829 return;
831 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
832 memcpy(&ra_tid->ra, ra, ETH_ALEN);
833 ra_tid->tid = tid;
835 skb->pkt_type = IEEE80211_DELBA_MSG;
836 skb_queue_tail(&local->skb_queue, skb);
837 tasklet_schedule(&local->tasklet);
839 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
842 * After accepting the AddBA Request we activated a timer,
843 * resetting it after each frame that arrives from the originator.
844 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
846 static void sta_rx_agg_session_timer_expired(unsigned long data)
848 /* not an elegant detour, but there is no choice as the timer passes
849 * only one argument, and various sta_info are needed here, so init
850 * flow in sta_info_create gives the TID as data, while the timer_to_id
851 * array gives the sta through container_of */
852 u8 *ptid = (u8 *)data;
853 u8 *timer_to_id = ptid - *ptid;
854 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
855 timer_to_tid[0]);
857 #ifdef CONFIG_MAC80211_HT_DEBUG
858 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
859 #endif
860 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
861 (u16)*ptid, WLAN_BACK_TIMER,
862 WLAN_REASON_QSTA_TIMEOUT);
865 void ieee80211_process_addba_request(struct ieee80211_local *local,
866 struct sta_info *sta,
867 struct ieee80211_mgmt *mgmt,
868 size_t len)
870 struct ieee80211_hw *hw = &local->hw;
871 struct ieee80211_conf *conf = &hw->conf;
872 struct tid_ampdu_rx *tid_agg_rx;
873 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
874 u8 dialog_token;
875 int ret = -EOPNOTSUPP;
877 /* extract session parameters from addba request frame */
878 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
879 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
880 start_seq_num =
881 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
883 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
884 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
885 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
886 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
888 status = WLAN_STATUS_REQUEST_DECLINED;
890 /* sanity check for incoming parameters:
891 * check if configuration can support the BA policy
892 * and if buffer size does not exceeds max value */
893 /* XXX: check own ht delayed BA capability?? */
894 if (((ba_policy != 1)
895 && (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA)))
896 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
897 status = WLAN_STATUS_INVALID_QOS_PARAM;
898 #ifdef CONFIG_MAC80211_HT_DEBUG
899 if (net_ratelimit())
900 printk(KERN_DEBUG "AddBA Req with bad params from "
901 "%pM on tid %u. policy %d, buffer size %d\n",
902 mgmt->sa, tid, ba_policy,
903 buf_size);
904 #endif /* CONFIG_MAC80211_HT_DEBUG */
905 goto end_no_lock;
907 /* determine default buffer size */
908 if (buf_size == 0) {
909 struct ieee80211_supported_band *sband;
911 sband = local->hw.wiphy->bands[conf->channel->band];
912 buf_size = IEEE80211_MIN_AMPDU_BUF;
913 buf_size = buf_size << sband->ht_cap.ampdu_factor;
917 /* examine state machine */
918 spin_lock_bh(&sta->lock);
920 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
921 #ifdef CONFIG_MAC80211_HT_DEBUG
922 if (net_ratelimit())
923 printk(KERN_DEBUG "unexpected AddBA Req from "
924 "%pM on tid %u\n",
925 mgmt->sa, tid);
926 #endif /* CONFIG_MAC80211_HT_DEBUG */
927 goto end;
930 /* prepare A-MPDU MLME for Rx aggregation */
931 sta->ampdu_mlme.tid_rx[tid] =
932 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
933 if (!sta->ampdu_mlme.tid_rx[tid]) {
934 #ifdef CONFIG_MAC80211_HT_DEBUG
935 if (net_ratelimit())
936 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
937 tid);
938 #endif
939 goto end;
941 /* rx timer */
942 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
943 sta_rx_agg_session_timer_expired;
944 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
945 (unsigned long)&sta->timer_to_tid[tid];
946 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
948 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
950 /* prepare reordering buffer */
951 tid_agg_rx->reorder_buf =
952 kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC);
953 if (!tid_agg_rx->reorder_buf) {
954 #ifdef CONFIG_MAC80211_HT_DEBUG
955 if (net_ratelimit())
956 printk(KERN_ERR "can not allocate reordering buffer "
957 "to tid %d\n", tid);
958 #endif
959 kfree(sta->ampdu_mlme.tid_rx[tid]);
960 goto end;
962 memset(tid_agg_rx->reorder_buf, 0,
963 buf_size * sizeof(struct sk_buff *));
965 if (local->ops->ampdu_action)
966 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
967 &sta->sta, tid, &start_seq_num);
968 #ifdef CONFIG_MAC80211_HT_DEBUG
969 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
970 #endif /* CONFIG_MAC80211_HT_DEBUG */
972 if (ret) {
973 kfree(tid_agg_rx->reorder_buf);
974 kfree(tid_agg_rx);
975 sta->ampdu_mlme.tid_rx[tid] = NULL;
976 goto end;
979 /* change state and send addba resp */
980 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
981 tid_agg_rx->dialog_token = dialog_token;
982 tid_agg_rx->ssn = start_seq_num;
983 tid_agg_rx->head_seq_num = start_seq_num;
984 tid_agg_rx->buf_size = buf_size;
985 tid_agg_rx->timeout = timeout;
986 tid_agg_rx->stored_mpdu_num = 0;
987 status = WLAN_STATUS_SUCCESS;
988 end:
989 spin_unlock_bh(&sta->lock);
991 end_no_lock:
992 ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
993 dialog_token, status, 1, buf_size, timeout);
996 void ieee80211_process_addba_resp(struct ieee80211_local *local,
997 struct sta_info *sta,
998 struct ieee80211_mgmt *mgmt,
999 size_t len)
1001 struct ieee80211_hw *hw = &local->hw;
1002 u16 capab;
1003 u16 tid, start_seq_num;
1004 u8 *state;
1006 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
1007 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1009 state = &sta->ampdu_mlme.tid_state_tx[tid];
1011 spin_lock_bh(&sta->lock);
1013 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1014 spin_unlock_bh(&sta->lock);
1015 return;
1018 if (mgmt->u.action.u.addba_resp.dialog_token !=
1019 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1020 spin_unlock_bh(&sta->lock);
1021 #ifdef CONFIG_MAC80211_HT_DEBUG
1022 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1023 #endif /* CONFIG_MAC80211_HT_DEBUG */
1024 return;
1027 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
1028 #ifdef CONFIG_MAC80211_HT_DEBUG
1029 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
1030 #endif /* CONFIG_MAC80211_HT_DEBUG */
1031 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
1032 == WLAN_STATUS_SUCCESS) {
1033 *state |= HT_ADDBA_RECEIVED_MSK;
1034 sta->ampdu_mlme.addba_req_num[tid] = 0;
1036 if (*state == HT_AGG_STATE_OPERATIONAL &&
1037 local->hw.ampdu_queues)
1038 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
1040 if (local->ops->ampdu_action) {
1041 (void)local->ops->ampdu_action(hw,
1042 IEEE80211_AMPDU_TX_RESUME,
1043 &sta->sta, tid, &start_seq_num);
1045 #ifdef CONFIG_MAC80211_HT_DEBUG
1046 printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
1047 #endif /* CONFIG_MAC80211_HT_DEBUG */
1048 spin_unlock_bh(&sta->lock);
1049 } else {
1050 sta->ampdu_mlme.addba_req_num[tid]++;
1051 /* this will allow the state check in stop_BA_session */
1052 *state = HT_AGG_STATE_OPERATIONAL;
1053 spin_unlock_bh(&sta->lock);
1054 ieee80211_stop_tx_ba_session(hw, sta->sta.addr, tid,
1055 WLAN_BACK_INITIATOR);
1059 void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
1060 struct sta_info *sta,
1061 struct ieee80211_mgmt *mgmt, size_t len)
1063 struct ieee80211_local *local = sdata->local;
1064 u16 tid, params;
1065 u16 initiator;
1067 params = le16_to_cpu(mgmt->u.action.u.delba.params);
1068 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
1069 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
1071 #ifdef CONFIG_MAC80211_HT_DEBUG
1072 if (net_ratelimit())
1073 printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n",
1074 mgmt->sa, initiator ? "initiator" : "recipient", tid,
1075 mgmt->u.action.u.delba.reason_code);
1076 #endif /* CONFIG_MAC80211_HT_DEBUG */
1078 if (initiator == WLAN_BACK_INITIATOR)
1079 ieee80211_sta_stop_rx_ba_session(sdata, sta->sta.addr, tid,
1080 WLAN_BACK_INITIATOR, 0);
1081 else { /* WLAN_BACK_RECIPIENT */
1082 spin_lock_bh(&sta->lock);
1083 sta->ampdu_mlme.tid_state_tx[tid] =
1084 HT_AGG_STATE_OPERATIONAL;
1085 spin_unlock_bh(&sta->lock);
1086 ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid,
1087 WLAN_BACK_RECIPIENT);