diff options
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r-- | net/mac80211/agg-tx.c | 64 |
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 | ||
109 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) | 107 | void 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 | } |
135 | EXPORT_SYMBOL(ieee80211_send_bar); | ||
138 | 136 | ||
139 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, | 137 | void 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 */ |