aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ht.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ht.c')
-rw-r--r--net/mac80211/ht.c265
1 files changed, 181 insertions, 84 deletions
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index dc7d9a3d70d5..5f510a13b9f0 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -20,50 +20,138 @@
20#include "sta_info.h" 20#include "sta_info.h"
21#include "wme.h" 21#include "wme.h"
22 22
23int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, 23void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
24 struct ieee80211_ht_info *ht_info) 24 struct ieee80211_ht_cap *ht_cap_ie,
25 struct ieee80211_sta_ht_cap *ht_cap)
25{ 26{
27 u8 ampdu_info, tx_mcs_set_cap;
28 int i, max_tx_streams;
26 29
27 if (ht_info == NULL) 30 BUG_ON(!ht_cap);
28 return -EINVAL; 31
32 memset(ht_cap, 0, sizeof(*ht_cap));
33
34 if (!ht_cap_ie)
35 return;
36
37 ht_cap->ht_supported = true;
29 38
30 memset(ht_info, 0, sizeof(*ht_info)); 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;
31 42
32 if (ht_cap_ie) { 43 ampdu_info = ht_cap_ie->ampdu_params_info;
33 u8 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;
34 48
35 ht_info->ht_supported = 1; 49 /* own MCS TX capabilities */
36 ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info); 50 tx_mcs_set_cap = sband->ht_cap.mcs.tx_params;
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);
42 } else
43 ht_info->ht_supported = 0;
44 51
45 return 0; 52 /* can we TX with MCS rates? */
53 if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED))
54 return;
55
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;
63
64 /*
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
70 */
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];
74
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];
81
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;
46} 85}
47 86
48int ieee80211_ht_addt_info_ie_to_ht_bss_info( 87/*
49 struct ieee80211_ht_addt_info *ht_add_info_ie, 88 * ieee80211_enable_ht should be called only after the operating band
50 struct ieee80211_ht_bss_info *bss_info) 89 * has been determined as ht configuration depends on the hw's
90 * HT abilities for a specific band.
91 */
92u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
93 struct ieee80211_ht_info *hti,
94 u16 ap_ht_cap_flags)
51{ 95{
52 if (bss_info == NULL) 96 struct ieee80211_local *local = sdata->local;
53 return -EINVAL; 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;
102
103 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
104
105 memset(&ht, 0, sizeof(ht));
106
107 /* HT is not supported */
108 if (!sband->ht_cap.ht_supported)
109 enable_ht = false;
110
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;
115
116 if (enable_ht) {
117 channel_type = NL80211_CHAN_HT20;
118
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;
129 }
130 }
131 }
132
133 ht_changed = local->hw.conf.ht.enabled != enable_ht ||
134 channel_type != local->hw.conf.ht.channel_type;
135
136 local->oper_channel_type = channel_type;
137 local->hw.conf.ht.enabled = enable_ht;
54 138
55 memset(bss_info, 0, sizeof(*bss_info)); 139 if (ht_changed)
140 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT);
56 141
57 if (ht_add_info_ie) { 142 /* disable HT */
58 u16 op_mode; 143 if (!enable_ht)
59 op_mode = le16_to_cpu(ht_add_info_ie->operation_mode); 144 return 0;
60 145
61 bss_info->primary_channel = ht_add_info_ie->control_chan; 146 ht.operation_mode = le16_to_cpu(hti->operation_mode);
62 bss_info->bss_cap = ht_add_info_ie->ht_param; 147
63 bss_info->bss_op_mode = (u8)(op_mode & 0xff); 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;
64 } 152 }
65 153
66 return 0; 154 return changed;
67} 155}
68 156
69static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, 157static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
@@ -241,7 +329,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r
241 struct ieee80211_hw *hw = &local->hw; 329 struct ieee80211_hw *hw = &local->hw;
242 struct sta_info *sta; 330 struct sta_info *sta;
243 int ret, i; 331 int ret, i;
244 DECLARE_MAC_BUF(mac);
245 332
246 rcu_read_lock(); 333 rcu_read_lock();
247 334
@@ -269,8 +356,8 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r
269 BUG_ON(!local->ops->ampdu_action); 356 BUG_ON(!local->ops->ampdu_action);
270 357
271#ifdef CONFIG_MAC80211_HT_DEBUG 358#ifdef CONFIG_MAC80211_HT_DEBUG
272 printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n", 359 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
273 print_mac(mac, ra), tid); 360 ra, tid);
274#endif /* CONFIG_MAC80211_HT_DEBUG */ 361#endif /* CONFIG_MAC80211_HT_DEBUG */
275 362
276 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, 363 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
@@ -383,14 +470,13 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
383 u16 start_seq_num; 470 u16 start_seq_num;
384 u8 *state; 471 u8 *state;
385 int ret; 472 int ret;
386 DECLARE_MAC_BUF(mac);
387 473
388 if (tid >= STA_TID_NUM) 474 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
389 return -EINVAL; 475 return -EINVAL;
390 476
391#ifdef CONFIG_MAC80211_HT_DEBUG 477#ifdef CONFIG_MAC80211_HT_DEBUG
392 printk(KERN_DEBUG "Open BA session requested for %s tid %u\n", 478 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
393 print_mac(mac, ra), tid); 479 ra, tid);
394#endif /* CONFIG_MAC80211_HT_DEBUG */ 480#endif /* CONFIG_MAC80211_HT_DEBUG */
395 481
396 rcu_read_lock(); 482 rcu_read_lock();
@@ -442,17 +528,19 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
442 (unsigned long)&sta->timer_to_tid[tid]; 528 (unsigned long)&sta->timer_to_tid[tid];
443 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 529 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
444 530
445 /* create a new queue for this aggregation */ 531 if (hw->ampdu_queues) {
446 ret = ieee80211_ht_agg_queue_add(local, sta, tid); 532 /* create a new queue for this aggregation */
533 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
447 534
448 /* case no queue is available to aggregation 535 /* case no queue is available to aggregation
449 * don't switch to aggregation */ 536 * don't switch to aggregation */
450 if (ret) { 537 if (ret) {
451#ifdef CONFIG_MAC80211_HT_DEBUG 538#ifdef CONFIG_MAC80211_HT_DEBUG
452 printk(KERN_DEBUG "BA request denied - queue unavailable for" 539 printk(KERN_DEBUG "BA request denied - "
453 " tid %d\n", tid); 540 "queue unavailable for tid %d\n", tid);
454#endif /* CONFIG_MAC80211_HT_DEBUG */ 541#endif /* CONFIG_MAC80211_HT_DEBUG */
455 goto err_unlock_queue; 542 goto err_unlock_queue;
543 }
456 } 544 }
457 sdata = sta->sdata; 545 sdata = sta->sdata;
458 546
@@ -471,7 +559,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
471 /* No need to requeue the packets in the agg queue, since we 559 /* 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 560 * held the tx lock: no packet could be enqueued to the newly
473 * allocated queue */ 561 * allocated queue */
474 ieee80211_ht_agg_queue_remove(local, sta, tid, 0); 562 if (hw->ampdu_queues)
563 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
475#ifdef CONFIG_MAC80211_HT_DEBUG 564#ifdef CONFIG_MAC80211_HT_DEBUG
476 printk(KERN_DEBUG "BA request denied - HW unavailable for" 565 printk(KERN_DEBUG "BA request denied - HW unavailable for"
477 " tid %d\n", tid); 566 " tid %d\n", tid);
@@ -481,7 +570,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
481 } 570 }
482 571
483 /* Will put all the packets in the new SW queue */ 572 /* Will put all the packets in the new SW queue */
484 ieee80211_requeue(local, ieee802_1d_to_ac[tid]); 573 if (hw->ampdu_queues)
574 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
485 spin_unlock_bh(&sta->lock); 575 spin_unlock_bh(&sta->lock);
486 576
487 /* send an addBA request */ 577 /* send an addBA request */
@@ -524,7 +614,6 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
524 struct sta_info *sta; 614 struct sta_info *sta;
525 u8 *state; 615 u8 *state;
526 int ret = 0; 616 int ret = 0;
527 DECLARE_MAC_BUF(mac);
528 617
529 if (tid >= STA_TID_NUM) 618 if (tid >= STA_TID_NUM)
530 return -EINVAL; 619 return -EINVAL;
@@ -546,11 +635,12 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
546 } 635 }
547 636
548#ifdef CONFIG_MAC80211_HT_DEBUG 637#ifdef CONFIG_MAC80211_HT_DEBUG
549 printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n", 638 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
550 print_mac(mac, ra), tid); 639 ra, tid);
551#endif /* CONFIG_MAC80211_HT_DEBUG */ 640#endif /* CONFIG_MAC80211_HT_DEBUG */
552 641
553 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); 642 if (hw->ampdu_queues)
643 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
554 644
555 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 645 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
556 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 646 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
@@ -563,7 +653,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
563 if (ret) { 653 if (ret) {
564 WARN_ON(ret != -EBUSY); 654 WARN_ON(ret != -EBUSY);
565 *state = HT_AGG_STATE_OPERATIONAL; 655 *state = HT_AGG_STATE_OPERATIONAL;
566 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 656 if (hw->ampdu_queues)
657 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
567 goto stop_BA_exit; 658 goto stop_BA_exit;
568 } 659 }
569 660
@@ -579,7 +670,6 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
579 struct ieee80211_local *local = hw_to_local(hw); 670 struct ieee80211_local *local = hw_to_local(hw);
580 struct sta_info *sta; 671 struct sta_info *sta;
581 u8 *state; 672 u8 *state;
582 DECLARE_MAC_BUF(mac);
583 673
584 if (tid >= STA_TID_NUM) { 674 if (tid >= STA_TID_NUM) {
585#ifdef CONFIG_MAC80211_HT_DEBUG 675#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -594,8 +684,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
594 if (!sta) { 684 if (!sta) {
595 rcu_read_unlock(); 685 rcu_read_unlock();
596#ifdef CONFIG_MAC80211_HT_DEBUG 686#ifdef CONFIG_MAC80211_HT_DEBUG
597 printk(KERN_DEBUG "Could not find station: %s\n", 687 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
598 print_mac(mac, ra));
599#endif 688#endif
600 return; 689 return;
601 } 690 }
@@ -621,7 +710,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
621#ifdef CONFIG_MAC80211_HT_DEBUG 710#ifdef CONFIG_MAC80211_HT_DEBUG
622 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); 711 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
623#endif 712#endif
624 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 713 if (hw->ampdu_queues)
714 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
625 } 715 }
626 spin_unlock_bh(&sta->lock); 716 spin_unlock_bh(&sta->lock);
627 rcu_read_unlock(); 717 rcu_read_unlock();
@@ -634,7 +724,6 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
634 struct sta_info *sta; 724 struct sta_info *sta;
635 u8 *state; 725 u8 *state;
636 int agg_queue; 726 int agg_queue;
637 DECLARE_MAC_BUF(mac);
638 727
639 if (tid >= STA_TID_NUM) { 728 if (tid >= STA_TID_NUM) {
640#ifdef CONFIG_MAC80211_HT_DEBUG 729#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -645,16 +734,15 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
645 } 734 }
646 735
647#ifdef CONFIG_MAC80211_HT_DEBUG 736#ifdef CONFIG_MAC80211_HT_DEBUG
648 printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n", 737 printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
649 print_mac(mac, ra), tid); 738 ra, tid);
650#endif /* CONFIG_MAC80211_HT_DEBUG */ 739#endif /* CONFIG_MAC80211_HT_DEBUG */
651 740
652 rcu_read_lock(); 741 rcu_read_lock();
653 sta = sta_info_get(local, ra); 742 sta = sta_info_get(local, ra);
654 if (!sta) { 743 if (!sta) {
655#ifdef CONFIG_MAC80211_HT_DEBUG 744#ifdef CONFIG_MAC80211_HT_DEBUG
656 printk(KERN_DEBUG "Could not find station: %s\n", 745 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
657 print_mac(mac, ra));
658#endif 746#endif
659 rcu_read_unlock(); 747 rcu_read_unlock();
660 return; 748 return;
@@ -677,16 +765,18 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
677 ieee80211_send_delba(sta->sdata, ra, tid, 765 ieee80211_send_delba(sta->sdata, ra, tid,
678 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 766 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
679 767
680 agg_queue = sta->tid_to_tx_q[tid]; 768 if (hw->ampdu_queues) {
681 769 agg_queue = sta->tid_to_tx_q[tid];
682 ieee80211_ht_agg_queue_remove(local, sta, tid, 1); 770 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
683 771
684 /* We just requeued the all the frames that were in the 772 /* We just requeued the all the frames that were in the
685 * removed queue, and since we might miss a softirq we do 773 * removed queue, and since we might miss a softirq we do
686 * netif_schedule_queue. ieee80211_wake_queue is not used 774 * netif_schedule_queue. ieee80211_wake_queue is not used
687 * here as this queue is not necessarily stopped 775 * here as this queue is not necessarily stopped
688 */ 776 */
689 netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue)); 777 netif_schedule_queue(netdev_get_tx_queue(local->mdev,
778 agg_queue));
779 }
690 spin_lock_bh(&sta->lock); 780 spin_lock_bh(&sta->lock);
691 *state = HT_AGG_STATE_IDLE; 781 *state = HT_AGG_STATE_IDLE;
692 sta->ampdu_mlme.addba_req_num[tid] = 0; 782 sta->ampdu_mlme.addba_req_num[tid] = 0;
@@ -783,7 +873,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
783 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; 873 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
784 u8 dialog_token; 874 u8 dialog_token;
785 int ret = -EOPNOTSUPP; 875 int ret = -EOPNOTSUPP;
786 DECLARE_MAC_BUF(mac);
787 876
788 /* extract session parameters from addba request frame */ 877 /* extract session parameters from addba request frame */
789 dialog_token = mgmt->u.action.u.addba_req.dialog_token; 878 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
@@ -801,15 +890,16 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
801 /* sanity check for incoming parameters: 890 /* sanity check for incoming parameters:
802 * check if configuration can support the BA policy 891 * check if configuration can support the BA policy
803 * and if buffer size does not exceeds max value */ 892 * and if buffer size does not exceeds max value */
893 /* XXX: check own ht delayed BA capability?? */
804 if (((ba_policy != 1) 894 if (((ba_policy != 1)
805 && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA))) 895 && (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA)))
806 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { 896 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
807 status = WLAN_STATUS_INVALID_QOS_PARAM; 897 status = WLAN_STATUS_INVALID_QOS_PARAM;
808#ifdef CONFIG_MAC80211_HT_DEBUG 898#ifdef CONFIG_MAC80211_HT_DEBUG
809 if (net_ratelimit()) 899 if (net_ratelimit())
810 printk(KERN_DEBUG "AddBA Req with bad params from " 900 printk(KERN_DEBUG "AddBA Req with bad params from "
811 "%s on tid %u. policy %d, buffer size %d\n", 901 "%pM on tid %u. policy %d, buffer size %d\n",
812 print_mac(mac, mgmt->sa), tid, ba_policy, 902 mgmt->sa, tid, ba_policy,
813 buf_size); 903 buf_size);
814#endif /* CONFIG_MAC80211_HT_DEBUG */ 904#endif /* CONFIG_MAC80211_HT_DEBUG */
815 goto end_no_lock; 905 goto end_no_lock;
@@ -820,7 +910,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
820 910
821 sband = local->hw.wiphy->bands[conf->channel->band]; 911 sband = local->hw.wiphy->bands[conf->channel->band];
822 buf_size = IEEE80211_MIN_AMPDU_BUF; 912 buf_size = IEEE80211_MIN_AMPDU_BUF;
823 buf_size = buf_size << sband->ht_info.ampdu_factor; 913 buf_size = buf_size << sband->ht_cap.ampdu_factor;
824 } 914 }
825 915
826 916
@@ -831,8 +921,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
831#ifdef CONFIG_MAC80211_HT_DEBUG 921#ifdef CONFIG_MAC80211_HT_DEBUG
832 if (net_ratelimit()) 922 if (net_ratelimit())
833 printk(KERN_DEBUG "unexpected AddBA Req from " 923 printk(KERN_DEBUG "unexpected AddBA Req from "
834 "%s on tid %u\n", 924 "%pM on tid %u\n",
835 print_mac(mac, mgmt->sa), tid); 925 mgmt->sa, tid);
836#endif /* CONFIG_MAC80211_HT_DEBUG */ 926#endif /* CONFIG_MAC80211_HT_DEBUG */
837 goto end; 927 goto end;
838 } 928 }
@@ -910,7 +1000,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
910{ 1000{
911 struct ieee80211_hw *hw = &local->hw; 1001 struct ieee80211_hw *hw = &local->hw;
912 u16 capab; 1002 u16 capab;
913 u16 tid; 1003 u16 tid, start_seq_num;
914 u8 *state; 1004 u8 *state;
915 1005
916 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 1006 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
@@ -943,9 +1033,18 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
943 *state |= HT_ADDBA_RECEIVED_MSK; 1033 *state |= HT_ADDBA_RECEIVED_MSK;
944 sta->ampdu_mlme.addba_req_num[tid] = 0; 1034 sta->ampdu_mlme.addba_req_num[tid] = 0;
945 1035
946 if (*state == HT_AGG_STATE_OPERATIONAL) 1036 if (*state == HT_AGG_STATE_OPERATIONAL &&
1037 local->hw.ampdu_queues)
947 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 1038 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
948 1039
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);
1044 }
1045#ifdef CONFIG_MAC80211_HT_DEBUG
1046 printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
1047#endif /* CONFIG_MAC80211_HT_DEBUG */
949 spin_unlock_bh(&sta->lock); 1048 spin_unlock_bh(&sta->lock);
950 } else { 1049 } else {
951 sta->ampdu_mlme.addba_req_num[tid]++; 1050 sta->ampdu_mlme.addba_req_num[tid]++;
@@ -964,7 +1063,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
964 struct ieee80211_local *local = sdata->local; 1063 struct ieee80211_local *local = sdata->local;
965 u16 tid, params; 1064 u16 tid, params;
966 u16 initiator; 1065 u16 initiator;
967 DECLARE_MAC_BUF(mac);
968 1066
969 params = le16_to_cpu(mgmt->u.action.u.delba.params); 1067 params = le16_to_cpu(mgmt->u.action.u.delba.params);
970 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; 1068 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
@@ -972,9 +1070,8 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
972 1070
973#ifdef CONFIG_MAC80211_HT_DEBUG 1071#ifdef CONFIG_MAC80211_HT_DEBUG
974 if (net_ratelimit()) 1072 if (net_ratelimit())
975 printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n", 1073 printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n",
976 print_mac(mac, mgmt->sa), 1074 mgmt->sa, initiator ? "initiator" : "recipient", tid,
977 initiator ? "initiator" : "recipient", tid,
978 mgmt->u.action.u.delba.reason_code); 1075 mgmt->u.action.u.delba.reason_code);
979#endif /* CONFIG_MAC80211_HT_DEBUG */ 1076#endif /* CONFIG_MAC80211_HT_DEBUG */
980 1077