aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r--net/mac80211/agg-tx.c65
1 files changed, 23 insertions, 42 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index c8be8eff70da..b3f65520e7a7 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -15,6 +15,7 @@
15 15
16#include <linux/ieee80211.h> 16#include <linux/ieee80211.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/export.h>
18#include <net/mac80211.h> 19#include <net/mac80211.h>
19#include "ieee80211_i.h" 20#include "ieee80211_i.h"
20#include "driver-ops.h" 21#include "driver-ops.h"
@@ -68,11 +69,9 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
68 69
69 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); 70 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
70 71
71 if (!skb) { 72 if (!skb)
72 printk(KERN_ERR "%s: failed to allocate buffer "
73 "for addba request frame\n", sdata->name);
74 return; 73 return;
75 } 74
76 skb_reserve(skb, local->hw.extra_tx_headroom); 75 skb_reserve(skb, local->hw.extra_tx_headroom);
77 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 76 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
78 memset(mgmt, 0, 24); 77 memset(mgmt, 0, 24);
@@ -106,19 +105,18 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
106 ieee80211_tx_skb(sdata, skb); 105 ieee80211_tx_skb(sdata, skb);
107} 106}
108 107
109void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) 108void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
110{ 109{
110 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
111 struct ieee80211_local *local = sdata->local; 111 struct ieee80211_local *local = sdata->local;
112 struct sk_buff *skb; 112 struct sk_buff *skb;
113 struct ieee80211_bar *bar; 113 struct ieee80211_bar *bar;
114 u16 bar_control = 0; 114 u16 bar_control = 0;
115 115
116 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); 116 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
117 if (!skb) { 117 if (!skb)
118 printk(KERN_ERR "%s: failed to allocate buffer for "
119 "bar frame\n", sdata->name);
120 return; 118 return;
121 } 119
122 skb_reserve(skb, local->hw.extra_tx_headroom); 120 skb_reserve(skb, local->hw.extra_tx_headroom);
123 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar)); 121 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
124 memset(bar, 0, sizeof(*bar)); 122 memset(bar, 0, sizeof(*bar));
@@ -128,13 +126,14 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
128 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN); 126 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN);
129 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; 127 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
130 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; 128 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
131 bar_control |= (u16)(tid << 12); 129 bar_control |= (u16)(tid << IEEE80211_BAR_CTRL_TID_INFO_SHIFT);
132 bar->control = cpu_to_le16(bar_control); 130 bar->control = cpu_to_le16(bar_control);
133 bar->start_seq_num = cpu_to_le16(ssn); 131 bar->start_seq_num = cpu_to_le16(ssn);
134 132
135 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 133 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
136 ieee80211_tx_skb(sdata, skb); 134 ieee80211_tx_skb(sdata, skb);
137} 135}
136EXPORT_SYMBOL(ieee80211_send_bar);
138 137
139void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, 138void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
140 struct tid_ampdu_tx *tid_tx) 139 struct tid_ampdu_tx *tid_tx)
@@ -364,7 +363,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
364 return -EINVAL; 363 return -EINVAL;
365 364
366 if ((tid >= STA_TID_NUM) || 365 if ((tid >= STA_TID_NUM) ||
367 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) 366 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) ||
367 (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW))
368 return -EINVAL; 368 return -EINVAL;
369 369
370#ifdef CONFIG_MAC80211_HT_DEBUG 370#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -383,7 +383,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
383 sdata->vif.type != NL80211_IFTYPE_AP) 383 sdata->vif.type != NL80211_IFTYPE_AP)
384 return -EINVAL; 384 return -EINVAL;
385 385
386 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { 386 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
387#ifdef CONFIG_MAC80211_HT_DEBUG 387#ifdef CONFIG_MAC80211_HT_DEBUG
388 printk(KERN_DEBUG "BA sessions blocked. " 388 printk(KERN_DEBUG "BA sessions blocked. "
389 "Denying BA session request\n"); 389 "Denying BA session request\n");
@@ -413,11 +413,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
413 /* prepare A-MPDU MLME for Tx aggregation */ 413 /* prepare A-MPDU MLME for Tx aggregation */
414 tid_tx = kzalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); 414 tid_tx = kzalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
415 if (!tid_tx) { 415 if (!tid_tx) {
416#ifdef CONFIG_MAC80211_HT_DEBUG
417 if (net_ratelimit())
418 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
419 tid);
420#endif
421 ret = -ENOMEM; 416 ret = -ENOMEM;
422 goto err_unlock_sta; 417 goto err_unlock_sta;
423 } 418 }
@@ -574,14 +569,9 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
574 struct ieee80211_ra_tid *ra_tid; 569 struct ieee80211_ra_tid *ra_tid;
575 struct sk_buff *skb = dev_alloc_skb(0); 570 struct sk_buff *skb = dev_alloc_skb(0);
576 571
577 if (unlikely(!skb)) { 572 if (unlikely(!skb))
578#ifdef CONFIG_MAC80211_HT_DEBUG
579 if (net_ratelimit())
580 printk(KERN_WARNING "%s: Not enough memory, "
581 "dropping start BA session", sdata->name);
582#endif
583 return; 573 return;
584 } 574
585 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 575 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
586 memcpy(&ra_tid->ra, ra, ETH_ALEN); 576 memcpy(&ra_tid->ra, ra, ETH_ALEN);
587 ra_tid->tid = tid; 577 ra_tid->tid = tid;
@@ -727,14 +717,9 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
727 struct ieee80211_ra_tid *ra_tid; 717 struct ieee80211_ra_tid *ra_tid;
728 struct sk_buff *skb = dev_alloc_skb(0); 718 struct sk_buff *skb = dev_alloc_skb(0);
729 719
730 if (unlikely(!skb)) { 720 if (unlikely(!skb))
731#ifdef CONFIG_MAC80211_HT_DEBUG
732 if (net_ratelimit())
733 printk(KERN_WARNING "%s: Not enough memory, "
734 "dropping stop BA session", sdata->name);
735#endif
736 return; 721 return;
737 } 722
738 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 723 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
739 memcpy(&ra_tid->ra, ra, ETH_ALEN); 724 memcpy(&ra_tid->ra, ra, ETH_ALEN);
740 ra_tid->tid = tid; 725 ra_tid->tid = tid;
@@ -777,18 +762,14 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
777#ifdef CONFIG_MAC80211_HT_DEBUG 762#ifdef CONFIG_MAC80211_HT_DEBUG
778 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); 763 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
779#endif 764#endif
780 765 /*
766 * IEEE 802.11-2007 7.3.1.14:
767 * In an ADDBA Response frame, when the Status Code field
768 * is set to 0, the Buffer Size subfield is set to a value
769 * of at least 1.
770 */
781 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 771 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
782 == WLAN_STATUS_SUCCESS) { 772 == WLAN_STATUS_SUCCESS && buf_size) {
783 /*
784 * IEEE 802.11-2007 7.3.1.14:
785 * In an ADDBA Response frame, when the Status Code field
786 * is set to 0, the Buffer Size subfield is set to a value
787 * of at least 1.
788 */
789 if (!buf_size)
790 goto out;
791
792 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED, 773 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
793 &tid_tx->state)) { 774 &tid_tx->state)) {
794 /* ignore duplicate response */ 775 /* ignore duplicate response */