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.c64
1 files changed, 22 insertions, 42 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index c8be8eff70da..2ac033989e01 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -68,11 +68,9 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
68 68
69 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); 69 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
70 70
71 if (!skb) { 71 if (!skb)
72 printk(KERN_ERR "%s: failed to allocate buffer "
73 "for addba request frame\n", sdata->name);
74 return; 72 return;
75 } 73
76 skb_reserve(skb, local->hw.extra_tx_headroom); 74 skb_reserve(skb, local->hw.extra_tx_headroom);
77 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 75 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
78 memset(mgmt, 0, 24); 76 memset(mgmt, 0, 24);
@@ -106,19 +104,18 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
106 ieee80211_tx_skb(sdata, skb); 104 ieee80211_tx_skb(sdata, skb);
107} 105}
108 106
109void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) 107void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
110{ 108{
109 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
111 struct ieee80211_local *local = sdata->local; 110 struct ieee80211_local *local = sdata->local;
112 struct sk_buff *skb; 111 struct sk_buff *skb;
113 struct ieee80211_bar *bar; 112 struct ieee80211_bar *bar;
114 u16 bar_control = 0; 113 u16 bar_control = 0;
115 114
116 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); 115 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
117 if (!skb) { 116 if (!skb)
118 printk(KERN_ERR "%s: failed to allocate buffer for "
119 "bar frame\n", sdata->name);
120 return; 117 return;
121 } 118
122 skb_reserve(skb, local->hw.extra_tx_headroom); 119 skb_reserve(skb, local->hw.extra_tx_headroom);
123 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar)); 120 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
124 memset(bar, 0, sizeof(*bar)); 121 memset(bar, 0, sizeof(*bar));
@@ -128,13 +125,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); 125 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN);
129 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; 126 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
130 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; 127 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
131 bar_control |= (u16)(tid << 12); 128 bar_control |= (u16)(tid << IEEE80211_BAR_CTRL_TID_INFO_SHIFT);
132 bar->control = cpu_to_le16(bar_control); 129 bar->control = cpu_to_le16(bar_control);
133 bar->start_seq_num = cpu_to_le16(ssn); 130 bar->start_seq_num = cpu_to_le16(ssn);
134 131
135 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 132 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
136 ieee80211_tx_skb(sdata, skb); 133 ieee80211_tx_skb(sdata, skb);
137} 134}
135EXPORT_SYMBOL(ieee80211_send_bar);
138 136
139void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, 137void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
140 struct tid_ampdu_tx *tid_tx) 138 struct tid_ampdu_tx *tid_tx)
@@ -364,7 +362,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
364 return -EINVAL; 362 return -EINVAL;
365 363
366 if ((tid >= STA_TID_NUM) || 364 if ((tid >= STA_TID_NUM) ||
367 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) 365 !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) ||
366 (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW))
368 return -EINVAL; 367 return -EINVAL;
369 368
370#ifdef CONFIG_MAC80211_HT_DEBUG 369#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -383,7 +382,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
383 sdata->vif.type != NL80211_IFTYPE_AP) 382 sdata->vif.type != NL80211_IFTYPE_AP)
384 return -EINVAL; 383 return -EINVAL;
385 384
386 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) { 385 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
387#ifdef CONFIG_MAC80211_HT_DEBUG 386#ifdef CONFIG_MAC80211_HT_DEBUG
388 printk(KERN_DEBUG "BA sessions blocked. " 387 printk(KERN_DEBUG "BA sessions blocked. "
389 "Denying BA session request\n"); 388 "Denying BA session request\n");
@@ -413,11 +412,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
413 /* prepare A-MPDU MLME for Tx aggregation */ 412 /* prepare A-MPDU MLME for Tx aggregation */
414 tid_tx = kzalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); 413 tid_tx = kzalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
415 if (!tid_tx) { 414 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; 415 ret = -ENOMEM;
422 goto err_unlock_sta; 416 goto err_unlock_sta;
423 } 417 }
@@ -574,14 +568,9 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
574 struct ieee80211_ra_tid *ra_tid; 568 struct ieee80211_ra_tid *ra_tid;
575 struct sk_buff *skb = dev_alloc_skb(0); 569 struct sk_buff *skb = dev_alloc_skb(0);
576 570
577 if (unlikely(!skb)) { 571 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; 572 return;
584 } 573
585 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 574 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
586 memcpy(&ra_tid->ra, ra, ETH_ALEN); 575 memcpy(&ra_tid->ra, ra, ETH_ALEN);
587 ra_tid->tid = tid; 576 ra_tid->tid = tid;
@@ -727,14 +716,9 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
727 struct ieee80211_ra_tid *ra_tid; 716 struct ieee80211_ra_tid *ra_tid;
728 struct sk_buff *skb = dev_alloc_skb(0); 717 struct sk_buff *skb = dev_alloc_skb(0);
729 718
730 if (unlikely(!skb)) { 719 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; 720 return;
737 } 721
738 ra_tid = (struct ieee80211_ra_tid *) &skb->cb; 722 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
739 memcpy(&ra_tid->ra, ra, ETH_ALEN); 723 memcpy(&ra_tid->ra, ra, ETH_ALEN);
740 ra_tid->tid = tid; 724 ra_tid->tid = tid;
@@ -777,18 +761,14 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
777#ifdef CONFIG_MAC80211_HT_DEBUG 761#ifdef CONFIG_MAC80211_HT_DEBUG
778 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); 762 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
779#endif 763#endif
780 764 /*
765 * IEEE 802.11-2007 7.3.1.14:
766 * In an ADDBA Response frame, when the Status Code field
767 * is set to 0, the Buffer Size subfield is set to a value
768 * of at least 1.
769 */
781 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 770 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
782 == WLAN_STATUS_SUCCESS) { 771 == 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, 772 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
793 &tid_tx->state)) { 773 &tid_tx->state)) {
794 /* ignore duplicate response */ 774 /* ignore duplicate response */