OLD | NEW |
1 /* | 1 /* |
2 * HT handling | 2 * HT handling |
3 * | 3 * |
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi> | 4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi> |
5 * Copyright 2002-2005, Instant802 Networks, Inc. | 5 * Copyright 2002-2005, Instant802 Networks, Inc. |
6 * Copyright 2005-2006, Devicescape Software, Inc. | 6 * Copyright 2005-2006, Devicescape Software, Inc. |
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
9 * Copyright 2007-2010, Intel Corporation | 9 * Copyright 2007-2010, Intel Corporation |
10 * | 10 * |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 138 |
139 static void kfree_tid_tx(struct rcu_head *rcu_head) | 139 static void kfree_tid_tx(struct rcu_head *rcu_head) |
140 { | 140 { |
141 struct tid_ampdu_tx *tid_tx = | 141 struct tid_ampdu_tx *tid_tx = |
142 container_of(rcu_head, struct tid_ampdu_tx, rcu_head); | 142 container_of(rcu_head, struct tid_ampdu_tx, rcu_head); |
143 | 143 |
144 kfree(tid_tx); | 144 kfree(tid_tx); |
145 } | 145 } |
146 | 146 |
147 int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 147 int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
148 » » » » enum ieee80211_back_parties initiator, | 148 » » » » enum ieee80211_back_parties initiator) |
149 » » » » bool tx) | |
150 { | 149 { |
151 struct ieee80211_local *local = sta->local; | 150 struct ieee80211_local *local = sta->local; |
152 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; | 151 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; |
153 int ret; | 152 int ret; |
154 | 153 |
155 lockdep_assert_held(&sta->ampdu_mlme.mtx); | 154 lockdep_assert_held(&sta->ampdu_mlme.mtx); |
156 | 155 |
157 if (!tid_tx) | 156 if (!tid_tx) |
158 return -ENOENT; | 157 return -ENOENT; |
159 | 158 |
(...skipping 19 matching lines...) Expand all Loading... |
179 del_timer_sync(&tid_tx->addba_resp_timer); | 178 del_timer_sync(&tid_tx->addba_resp_timer); |
180 | 179 |
181 /* | 180 /* |
182 * After this packets are no longer handed right through | 181 * After this packets are no longer handed right through |
183 * to the driver but are put onto tid_tx->pending instead, | 182 * to the driver but are put onto tid_tx->pending instead, |
184 * with locking to ensure proper access. | 183 * with locking to ensure proper access. |
185 */ | 184 */ |
186 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); | 185 clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); |
187 | 186 |
188 tid_tx->stop_initiator = initiator; | 187 tid_tx->stop_initiator = initiator; |
189 tid_tx->tx_stop = tx; | |
190 | 188 |
191 ret = drv_ampdu_action(local, sta->sdata, | 189 ret = drv_ampdu_action(local, sta->sdata, |
192 IEEE80211_AMPDU_TX_STOP, | 190 IEEE80211_AMPDU_TX_STOP, |
193 &sta->sta, tid, NULL); | 191 &sta->sta, tid, NULL); |
194 | 192 |
195 /* HW shall not deny going back to legacy */ | 193 /* HW shall not deny going back to legacy */ |
196 if (WARN_ON(ret)) { | 194 if (WARN_ON(ret)) { |
197 /* | 195 /* |
198 * We may have pending packets get stuck in this case... | 196 * We may have pending packets get stuck in this case... |
199 * Not bothering with a workaround for now. | 197 * Not bothering with a workaround for now. |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 memcpy(&ra_tid->ra, ra, ETH_ALEN); | 570 memcpy(&ra_tid->ra, ra, ETH_ALEN); |
573 ra_tid->tid = tid; | 571 ra_tid->tid = tid; |
574 | 572 |
575 skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_START; | 573 skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_START; |
576 skb_queue_tail(&sdata->skb_queue, skb); | 574 skb_queue_tail(&sdata->skb_queue, skb); |
577 ieee80211_queue_work(&local->hw, &sdata->work); | 575 ieee80211_queue_work(&local->hw, &sdata->work); |
578 } | 576 } |
579 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); | 577 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); |
580 | 578 |
581 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 579 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
582 » » » » enum ieee80211_back_parties initiator, | 580 » » » » enum ieee80211_back_parties initiator) |
583 » » » » bool tx) | |
584 { | 581 { |
585 int ret; | 582 int ret; |
586 | 583 |
587 mutex_lock(&sta->ampdu_mlme.mtx); | 584 mutex_lock(&sta->ampdu_mlme.mtx); |
588 | 585 |
589 » ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx); | 586 » ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); |
590 | 587 |
591 mutex_unlock(&sta->ampdu_mlme.mtx); | 588 mutex_unlock(&sta->ampdu_mlme.mtx); |
592 | 589 |
593 return ret; | 590 return ret; |
594 } | 591 } |
595 | 592 |
596 int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) | 593 int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) |
597 { | 594 { |
598 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 595 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
599 struct ieee80211_sub_if_data *sdata = sta->sdata; | 596 struct ieee80211_sub_if_data *sdata = sta->sdata; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 spin_lock_bh(&sta->lock); | 665 spin_lock_bh(&sta->lock); |
669 tid_tx = sta->ampdu_mlme.tid_tx[tid]; | 666 tid_tx = sta->ampdu_mlme.tid_tx[tid]; |
670 | 667 |
671 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { | 668 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { |
672 #ifdef CONFIG_MAC80211_HT_DEBUG | 669 #ifdef CONFIG_MAC80211_HT_DEBUG |
673 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 670 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
674 #endif | 671 #endif |
675 goto unlock_sta; | 672 goto unlock_sta; |
676 } | 673 } |
677 | 674 |
678 » if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop) | 675 » if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR) |
679 ieee80211_send_delba(sta->sdata, ra, tid, | 676 ieee80211_send_delba(sta->sdata, ra, tid, |
680 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | 677 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); |
681 | 678 |
682 /* | 679 /* |
683 * When we get here, the TX path will not be lockless any more wrt. | 680 * When we get here, the TX path will not be lockless any more wrt. |
684 * aggregation, since the OPERATIONAL bit has long been cleared. | 681 * aggregation, since the OPERATIONAL bit has long been cleared. |
685 * Thus it will block on getting the lock, if it occurs. So if we | 682 * Thus it will block on getting the lock, if it occurs. So if we |
686 * stop the queue now, we will not get any more packets, and any | 683 * stop the queue now, we will not get any more packets, and any |
687 * that might be being processed will wait for us here, thereby | 684 * that might be being processed will wait for us here, thereby |
688 * guaranteeing that no packets go to the tid_tx pending queue any | 685 * guaranteeing that no packets go to the tid_tx pending queue any |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 &tid_tx->state)) { | 765 &tid_tx->state)) { |
769 /* ignore duplicate response */ | 766 /* ignore duplicate response */ |
770 goto out; | 767 goto out; |
771 } | 768 } |
772 | 769 |
773 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)) | 770 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)) |
774 ieee80211_agg_tx_operational(local, sta, tid); | 771 ieee80211_agg_tx_operational(local, sta, tid); |
775 | 772 |
776 sta->ampdu_mlme.addba_req_num[tid] = 0; | 773 sta->ampdu_mlme.addba_req_num[tid] = 0; |
777 } else { | 774 } else { |
778 » » ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR, | 775 » » ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
779 » » » » » » true); | |
780 } | 776 } |
781 | 777 |
782 out: | 778 out: |
783 mutex_unlock(&sta->ampdu_mlme.mtx); | 779 mutex_unlock(&sta->ampdu_mlme.mtx); |
784 } | 780 } |
OLD | NEW |